diff options
Diffstat (limited to 'internal/federation')
-rw-r--r-- | internal/federation/dereferencing/account.go | 30 | ||||
-rw-r--r-- | internal/federation/dereferencing/error.go | 14 | ||||
-rw-r--r-- | internal/federation/dereferencing/status.go | 75 | ||||
-rw-r--r-- | internal/federation/federatingactor.go | 271 | ||||
-rw-r--r-- | internal/federation/federatingprotocol.go | 89 | ||||
-rw-r--r-- | internal/federation/handshake.go | 18 |
6 files changed, 229 insertions, 268 deletions
diff --git a/internal/federation/dereferencing/account.go b/internal/federation/dereferencing/account.go index 0ce35b0e4..4795db733 100644 --- a/internal/federation/dereferencing/account.go +++ b/internal/federation/dereferencing/account.go @@ -357,39 +357,13 @@ func (d *deref) enrichAccount(ctx context.Context, requestUser string, uri *url. // dereferenceAccountable calls remoteAccountID with a GET request, and tries to parse whatever // it finds as something that an account model can be constructed out of. -// -// Will work for Person, Application, or Service models. func (d *deref) dereferenceAccountable(ctx context.Context, transport transport.Transport, remoteAccountID *url.URL) (ap.Accountable, error) { b, err := transport.Dereference(ctx, remoteAccountID) if err != nil { - return nil, fmt.Errorf("DereferenceAccountable: error deferencing %s: %w", remoteAccountID.String(), err) - } - - m := make(map[string]interface{}) - if err := json.Unmarshal(b, &m); err != nil { - return nil, fmt.Errorf("DereferenceAccountable: error unmarshalling bytes into json: %w", err) - } - - t, err := streams.ToType(ctx, m) - if err != nil { - return nil, fmt.Errorf("DereferenceAccountable: error resolving json into ap vocab type: %w", err) - } - - //nolint:forcetypeassert - switch t.GetTypeName() { - case ap.ActorApplication: - return t.(vocab.ActivityStreamsApplication), nil - case ap.ActorGroup: - return t.(vocab.ActivityStreamsGroup), nil - case ap.ActorOrganization: - return t.(vocab.ActivityStreamsOrganization), nil - case ap.ActorPerson: - return t.(vocab.ActivityStreamsPerson), nil - case ap.ActorService: - return t.(vocab.ActivityStreamsService), nil + return nil, fmt.Errorf("dereferenceAccountable: error deferencing %s: %w", remoteAccountID.String(), err) } - return nil, newErrWrongType(fmt.Errorf("DereferenceAccountable: type name %s not supported as Accountable", t.GetTypeName())) + return ap.ResolveAccountable(ctx, b) } func (d *deref) fetchRemoteAccountAvatar(ctx context.Context, tsport transport.Transport, avatarURL string, accountID string) (string, error) { diff --git a/internal/federation/dereferencing/error.go b/internal/federation/dereferencing/error.go index f2fae63ac..769150cef 100644 --- a/internal/federation/dereferencing/error.go +++ b/internal/federation/dereferencing/error.go @@ -66,20 +66,6 @@ func newErrTransportError(err error) error { return &ErrTransportError{wrapped: err} } -// ErrWrongType indicates that an unexpected type was returned from a remote call; -// for example, we were served a Person when we were looking for a statusable. -type ErrWrongType struct { - wrapped error -} - -func (err *ErrWrongType) Error() string { - return fmt.Sprintf("wrong received type: %v", err.wrapped) -} - -func newErrWrongType(err error) error { - return &ErrWrongType{wrapped: err} -} - // ErrOther denotes some other kind of weird error, perhaps from a malformed json // or some other weird crapola. type ErrOther struct { diff --git a/internal/federation/dereferencing/status.go b/internal/federation/dereferencing/status.go index 8e202d585..fe07be23a 100644 --- a/internal/federation/dereferencing/status.go +++ b/internal/federation/dereferencing/status.go @@ -19,14 +19,11 @@ package dereferencing import ( "context" - "encoding/json" "errors" "fmt" "net/url" "strings" - "github.com/superseriousbusiness/activity/streams" - "github.com/superseriousbusiness/activity/streams/vocab" "github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" @@ -161,78 +158,10 @@ func (d *deref) dereferenceStatusable(ctx context.Context, tsport transport.Tran b, err := tsport.Dereference(ctx, remoteStatusID) if err != nil { - return nil, fmt.Errorf("DereferenceStatusable: error deferencing %s: %s", remoteStatusID.String(), err) + return nil, fmt.Errorf("dereferenceStatusable: error deferencing %s: %w", remoteStatusID.String(), err) } - m := make(map[string]interface{}) - if err := json.Unmarshal(b, &m); err != nil { - return nil, fmt.Errorf("DereferenceStatusable: error unmarshalling bytes into json: %s", err) - } - - t, err := streams.ToType(ctx, m) - if err != nil { - return nil, fmt.Errorf("DereferenceStatusable: error resolving json into ap vocab type: %s", err) - } - - // Article, Document, Image, Video, Note, Page, Event, Place, Mention, Profile - switch t.GetTypeName() { - case ap.ObjectArticle: - p, ok := t.(vocab.ActivityStreamsArticle) - if !ok { - return nil, errors.New("DereferenceStatusable: error resolving type as ActivityStreamsArticle") - } - return p, nil - case ap.ObjectDocument: - p, ok := t.(vocab.ActivityStreamsDocument) - if !ok { - return nil, errors.New("DereferenceStatusable: error resolving type as ActivityStreamsDocument") - } - return p, nil - case ap.ObjectImage: - p, ok := t.(vocab.ActivityStreamsImage) - if !ok { - return nil, errors.New("DereferenceStatusable: error resolving type as ActivityStreamsImage") - } - return p, nil - case ap.ObjectVideo: - p, ok := t.(vocab.ActivityStreamsVideo) - if !ok { - return nil, errors.New("DereferenceStatusable: error resolving type as ActivityStreamsVideo") - } - return p, nil - case ap.ObjectNote: - p, ok := t.(vocab.ActivityStreamsNote) - if !ok { - return nil, errors.New("DereferenceStatusable: error resolving type as ActivityStreamsNote") - } - return p, nil - case ap.ObjectPage: - p, ok := t.(vocab.ActivityStreamsPage) - if !ok { - return nil, errors.New("DereferenceStatusable: error resolving type as ActivityStreamsPage") - } - return p, nil - case ap.ObjectEvent: - p, ok := t.(vocab.ActivityStreamsEvent) - if !ok { - return nil, errors.New("DereferenceStatusable: error resolving type as ActivityStreamsEvent") - } - return p, nil - case ap.ObjectPlace: - p, ok := t.(vocab.ActivityStreamsPlace) - if !ok { - return nil, errors.New("DereferenceStatusable: error resolving type as ActivityStreamsPlace") - } - return p, nil - case ap.ObjectProfile: - p, ok := t.(vocab.ActivityStreamsProfile) - if !ok { - return nil, errors.New("DereferenceStatusable: error resolving type as ActivityStreamsProfile") - } - return p, nil - } - - return nil, newErrWrongType(fmt.Errorf("DereferenceStatusable: type name %s not supported as Statusable", t.GetTypeName())) + return ap.ResolveStatusable(ctx, b) } // populateStatusFields fetches all the information we temporarily pinned to an incoming diff --git a/internal/federation/federatingactor.go b/internal/federation/federatingactor.go index eec45d0ba..18cdf2106 100644 --- a/internal/federation/federatingactor.go +++ b/internal/federation/federatingactor.go @@ -19,133 +19,218 @@ package federation import ( "context" + "encoding/json" + "fmt" + "io" "net/http" "net/url" + "strings" + "codeberg.org/gruf/go-kv" "github.com/superseriousbusiness/activity/pub" + "github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/activity/streams/vocab" + "github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/log" ) -// federatingActor implements the go-fed federating protocol interface +// Potential incoming Content-Type header values; be +// lenient with whitespace and quotation mark placement. +var activityStreamsMediaTypes = []string{ + "application/activity+json", + "application/ld+json;profile=https://www.w3.org/ns/activitystreams", + "application/ld+json;profile=\"https://www.w3.org/ns/activitystreams\"", + "application/ld+json ;profile=https://www.w3.org/ns/activitystreams", + "application/ld+json ;profile=\"https://www.w3.org/ns/activitystreams\"", + "application/ld+json ; profile=https://www.w3.org/ns/activitystreams", + "application/ld+json ; profile=\"https://www.w3.org/ns/activitystreams\"", + "application/ld+json; profile=https://www.w3.org/ns/activitystreams", + "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"", +} + +// federatingActor wraps the pub.FederatingActor interface +// with some custom GoToSocial-specific logic. type federatingActor struct { - actor pub.FederatingActor + sideEffectActor pub.DelegateActor + wrapped pub.FederatingActor } -// newFederatingProtocol returns the gotosocial implementation of the GTSFederatingProtocol interface +// newFederatingProtocol returns a new federatingActor, which +// implements the pub.FederatingActor interface. func newFederatingActor(c pub.CommonBehavior, s2s pub.FederatingProtocol, db pub.Database, clock pub.Clock) pub.FederatingActor { - actor := pub.NewFederatingActor(c, s2s, db, clock) + sideEffectActor := pub.NewSideEffectActor(c, s2s, nil, db, clock) + customActor := pub.NewCustomActor(sideEffectActor, false, true, clock) return &federatingActor{ - actor: actor, + sideEffectActor: sideEffectActor, + wrapped: customActor, } } -// Send a federated activity. -// -// The provided url must be the outbox of the sender. All processing of -// the activity occurs similarly to the C2S flow: -// - If t is not an Activity, it is wrapped in a Create activity. -// - A new ID is generated for the activity. -// - The activity is added to the specified outbox. -// - The activity is prepared and delivered to recipients. -// -// Note that this function will only behave as expected if the -// implementation has been constructed to support federation. This -// method will guaranteed work for non-custom Actors. For custom actors, -// care should be used to not call this method if only C2S is supported. func (f *federatingActor) Send(c context.Context, outbox *url.URL, t vocab.Type) (pub.Activity, error) { log.Infof(c, "send activity %s via outbox %s", t.GetTypeName(), outbox) - return f.actor.Send(c, outbox, t) + return f.wrapped.Send(c, outbox, t) } -// PostInbox returns true if the request was handled as an ActivityPub -// POST to an actor's inbox. If false, the request was not an -// ActivityPub request and may still be handled by the caller in -// another way, such as serving a web page. -// -// If the error is nil, then the ResponseWriter's headers and response -// has already been written. If a non-nil error is returned, then no -// response has been written. -// -// If the Actor was constructed with the Federated Protocol enabled, -// side effects will occur. -// -// If the Federated Protocol is not enabled, writes the -// http.StatusMethodNotAllowed status code in the response. No side -// effects occur. func (f *federatingActor) PostInbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { - return f.actor.PostInbox(c, w, r) + return f.PostInboxScheme(c, w, r, "https") } -// PostInboxScheme is similar to PostInbox, except clients are able to -// specify which protocol scheme to handle the incoming request and the -// data stored within the application (HTTP, HTTPS, etc). -func (f *federatingActor) PostInboxScheme(c context.Context, w http.ResponseWriter, r *http.Request, scheme string) (bool, error) { - return f.actor.PostInboxScheme(c, w, r, scheme) +// PostInboxScheme is a reimplementation of the default baseActor +// implementation of PostInboxScheme in pub/base_actor.go. +// +// Key differences from that implementation: +// - More explicit debug logging when a request is not processed. +// - Normalize content of activity object. +// - Return code 202 instead of 200 on successful POST, to reflect +// that we process most side effects asynchronously. +func (f *federatingActor) PostInboxScheme(ctx context.Context, w http.ResponseWriter, r *http.Request, scheme string) (bool, error) { + l := log. + WithContext(ctx). + WithFields([]kv.Field{ + {"userAgent", r.UserAgent()}, + {"path", r.URL.Path}, + }...) + + // Do nothing if this is not an ActivityPub POST request. + if !func() bool { + if r.Method != http.MethodPost { + l.Debugf("inbox request was %s rather than required POST", r.Method) + return false + } + + contentType := r.Header.Get("Content-Type") + for _, mediaType := range activityStreamsMediaTypes { + if strings.Contains(contentType, mediaType) { + return true + } + } + + l.Debugf("inbox POST request content-type %s was not recognized", contentType) + return false + }() { + return false, nil + } + + // Check the peer request is authentic. + ctx, authenticated, err := f.sideEffectActor.AuthenticatePostInbox(ctx, w, r) + if err != nil { + return true, err + } else if !authenticated { + return true, nil + } + + // Begin processing the request, but note that we have + // not yet applied authorization (ex: blocks). + // + // Obtain the activity and reject unknown activities. + b, err := io.ReadAll(r.Body) + if err != nil { + err = fmt.Errorf("PostInboxScheme: error reading request body: %w", err) + return true, err + } + + var rawActivity map[string]interface{} + if err := json.Unmarshal(b, &rawActivity); err != nil { + err = fmt.Errorf("PostInboxScheme: error unmarshalling request body: %w", err) + return true, err + } + + t, err := streams.ToType(ctx, rawActivity) + if err != nil { + if !streams.IsUnmatchedErr(err) { + // Real error. + err = fmt.Errorf("PostInboxScheme: error matching json to type: %w", err) + return true, err + } + // Respond with bad request; we just couldn't + // match the type to one that we know about. + l.Debug("json could not be resolved to ActivityStreams value") + w.WriteHeader(http.StatusBadRequest) + return true, nil + } + + activity, ok := t.(pub.Activity) + if !ok { + err = fmt.Errorf("ActivityStreams value with type %T is not a pub.Activity", t) + return true, err + } + + if activity.GetJSONLDId() == nil { + l.Debugf("incoming Activity %s did not have required id property set", activity.GetTypeName()) + w.WriteHeader(http.StatusBadRequest) + return true, nil + } + + // If activity Object is a Statusable, we'll want to replace the + // parsed `content` value with the value from the raw JSON instead. + // See https://github.com/superseriousbusiness/gotosocial/issues/1661 + ap.NormalizeActivityObject(activity, rawActivity) + + // Allow server implementations to set context data with a hook. + ctx, err = f.sideEffectActor.PostInboxRequestBodyHook(ctx, r, activity) + if err != nil { + return true, err + } + + // Check authorization of the activity. + authorized, err := f.sideEffectActor.AuthorizePostInbox(ctx, w, activity) + if err != nil { + return true, err + } else if !authorized { + return true, nil + } + + // Copy existing URL + add request host and scheme. + inboxID := func() *url.URL { + id := &url.URL{} + *id = *r.URL + id.Host = r.Host + id.Scheme = scheme + return id + }() + + // Post the activity to the actor's inbox and trigger side effects for + // that particular Activity type. It is up to the delegate to resolve + // the given map. + if err := f.sideEffectActor.PostInbox(ctx, inboxID, activity); err != nil { + // Special case: We know it is a bad request if the object or + // target properties needed to be populated, but weren't. + // + // Send the rejection to the peer. + if err == pub.ErrObjectRequired || err == pub.ErrTargetRequired { + l.Debugf("malformed incoming Activity: %s", err) + w.WriteHeader(http.StatusBadRequest) + return true, nil + } + err = fmt.Errorf("PostInboxScheme: error calling sideEffectActor.PostInbox: %w", err) + return true, err + } + + // Our side effects are complete, now delegate determining whether to do inbox forwarding, as well as the action to do it. + if err := f.sideEffectActor.InboxForwarding(ctx, inboxID, activity); err != nil { + err = fmt.Errorf("PostInboxScheme: error calling sideEffectActor.InboxForwarding: %w", err) + return true, err + } + + // Request is now undergoing processing. + // Respond with an Accepted status. + w.WriteHeader(http.StatusAccepted) + return true, nil } -// GetInbox returns true if the request was handled as an ActivityPub -// GET to an actor's inbox. If false, the request was not an ActivityPub -// request and may still be handled by the caller in another way, such -// as serving a web page. -// -// If the error is nil, then the ResponseWriter's headers and response -// has already been written. If a non-nil error is returned, then no -// response has been written. -// -// If the request is an ActivityPub request, the Actor will defer to the -// application to determine the correct authorization of the request and -// the resulting OrderedCollection to respond with. The Actor handles -// serializing this OrderedCollection and responding with the correct -// headers and http.StatusOK. func (f *federatingActor) GetInbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { - return f.actor.GetInbox(c, w, r) + return f.wrapped.GetInbox(c, w, r) } -// PostOutbox returns true if the request was handled as an ActivityPub -// POST to an actor's outbox. If false, the request was not an -// ActivityPub request and may still be handled by the caller in another -// way, such as serving a web page. -// -// If the error is nil, then the ResponseWriter's headers and response -// has already been written. If a non-nil error is returned, then no -// response has been written. -// -// If the Actor was constructed with the Social Protocol enabled, side -// effects will occur. -// -// If the Social Protocol is not enabled, writes the -// http.StatusMethodNotAllowed status code in the response. No side -// effects occur. -// -// If the Social and Federated Protocol are both enabled, it will handle -// the side effects of receiving an ActivityStream Activity, and then -// federate the Activity to peers. func (f *federatingActor) PostOutbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { - return f.actor.PostOutbox(c, w, r) + return f.wrapped.PostOutbox(c, w, r) } -// PostOutboxScheme is similar to PostOutbox, except clients are able to -// specify which protocol scheme to handle the incoming request and the -// data stored within the application (HTTP, HTTPS, etc). func (f *federatingActor) PostOutboxScheme(c context.Context, w http.ResponseWriter, r *http.Request, scheme string) (bool, error) { - return f.actor.PostOutboxScheme(c, w, r, scheme) + return f.wrapped.PostOutboxScheme(c, w, r, scheme) } -// GetOutbox returns true if the request was handled as an ActivityPub -// GET to an actor's outbox. If false, the request was not an -// ActivityPub request. -// -// If the error is nil, then the ResponseWriter's headers and response -// has already been written. If a non-nil error is returned, then no -// response has been written. -// -// If the request is an ActivityPub request, the Actor will defer to the -// application to determine the correct authorization of the request and -// the resulting OrderedCollection to respond with. The Actor handles -// serializing this OrderedCollection and responding with the correct -// headers and http.StatusOK. func (f *federatingActor) GetOutbox(c context.Context, w http.ResponseWriter, r *http.Request) (bool, error) { - return f.actor.GetOutbox(c, w, r) + return f.wrapped.GetOutbox(c, w, r) } diff --git a/internal/federation/federatingprotocol.go b/internal/federation/federatingprotocol.go index ed0a216fe..52f46586d 100644 --- a/internal/federation/federatingprotocol.go +++ b/internal/federation/federatingprotocol.go @@ -24,7 +24,6 @@ import ( "net/http" "net/url" - "codeberg.org/gruf/go-kv" "github.com/superseriousbusiness/activity/pub" "github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/activity/streams/vocab" @@ -138,74 +137,80 @@ func (f *federator) PostInboxRequestBodyHook(ctx context.Context, r *http.Reques // authenticated must be true and error nil. The request will continue // to be processed. func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) { - l := log.WithContext(ctx). - WithFields(kv.Fields{ - {"useragent", r.UserAgent()}, - {"url", r.URL.String()}, - }...) - l.Trace("received request to authenticate") - - if !uris.IsInboxPath(r.URL) { - return nil, false, fmt.Errorf("path %s was not an inbox path", r.URL.String()) - } + log.Tracef(ctx, "received request to authenticate inbox %s", r.URL.String()) + // Ensure this is an inbox path, and fetch the inbox owner + // account by parsing username from `/users/{username}/inbox`. username, err := uris.ParseInboxPath(r.URL) if err != nil { - return nil, false, fmt.Errorf("could not parse path %s: %s", r.URL.String(), err) + err = fmt.Errorf("AuthenticatePostInbox: could not parse %s as inbox path: %w", r.URL.String(), err) + return nil, false, err } if username == "" { - return nil, false, errors.New("username was empty") + err = errors.New("AuthenticatePostInbox: inbox username was empty") + return nil, false, err } receivingAccount, err := f.db.GetAccountByUsernameDomain(ctx, username, "") if err != nil { - return nil, false, fmt.Errorf("could not fetch receiving account with username %s: %s", username, err) + err = fmt.Errorf("AuthenticatePostInbox: could not fetch receiving account %s: %w", username, err) + return nil, false, err } + // Check who's delivering by inspecting the http signature. publicKeyOwnerURI, errWithCode := f.AuthenticateFederatedRequest(ctx, receivingAccount.Username) if errWithCode != nil { switch errWithCode.Code() { case http.StatusUnauthorized, http.StatusForbidden, http.StatusBadRequest: - // if 400, 401, or 403, obey the interface by writing the header and bailing + // If codes 400, 401, or 403, obey the go-fed + // interface by writing the header and bailing. w.WriteHeader(errWithCode.Code()) return ctx, false, nil case http.StatusGone: - // if the requesting account has gone (http 410) then likely - // inbox post was a delete, we can just write 202 and leave, - // since we didn't know about the account anyway, so we can't - // do any further processing + // If the requesting account's key has gone + // (410) then likely inbox post was a delete. + // + // We can just write 202 and leave: we didn't + // know about the account anyway, so we can't + // do any further processing. w.WriteHeader(http.StatusAccepted) return ctx, false, nil default: - // if not, there's been a proper error + // Proper error. return ctx, false, err } } - // authentication has passed, so add an instance entry for this instance if it hasn't been done already - i := >smodel.Instance{} - if err := f.db.GetWhere(ctx, []db.Where{{Key: "domain", Value: publicKeyOwnerURI.Host}}, i); err != nil { - if err != db.ErrNoEntries { - // there's been an actual error - return ctx, false, fmt.Errorf("error getting requesting account with public key id %s: %s", publicKeyOwnerURI.String(), err) + // Authentication has passed, check if we need to create a + // new instance entry for the Host of the requesting account. + if _, err := f.db.GetInstance(ctx, publicKeyOwnerURI.Host); err != nil { + if !errors.Is(err, db.ErrNoEntries) { + // There's been an actual error. + err = fmt.Errorf("AuthenticatePostInbox: error getting instance %s: %w", publicKeyOwnerURI.Host, err) + return ctx, false, err } - // we don't have an entry for this instance yet so dereference it - i, err = f.GetRemoteInstance(transport.WithFastfail(ctx), username, &url.URL{ + // We don't yet have an entry for + // the instance, go dereference it. + instance, err := f.GetRemoteInstance(transport.WithFastfail(ctx), username, &url.URL{ Scheme: publicKeyOwnerURI.Scheme, Host: publicKeyOwnerURI.Host, }) if err != nil { - return nil, false, fmt.Errorf("could not dereference new remote instance %s during AuthenticatePostInbox: %s", publicKeyOwnerURI.Host, err) + err = fmt.Errorf("AuthenticatePostInbox: error dereferencing instance %s: %w", publicKeyOwnerURI.Host, err) + return nil, false, err } - // and put it in the db - if err := f.db.Put(ctx, i); err != nil { - return nil, false, fmt.Errorf("error inserting newly dereferenced instance %s: %s", publicKeyOwnerURI.Host, err) + if err := f.db.Put(ctx, instance); err != nil { + err = fmt.Errorf("AuthenticatePostInbox: error inserting instance entry for %s: %w", publicKeyOwnerURI.Host, err) + return nil, false, err } } + // We know the public key owner URI now, so we can + // dereference the remote account (or just get it + // from the db if we already have it). requestingAccount, err := f.GetAccountByURI( transport.WithFastfail(ctx), username, publicKeyOwnerURI, false, ) @@ -220,9 +225,12 @@ func (f *federator) AuthenticatePostInbox(ctx context.Context, w http.ResponseWr w.WriteHeader(http.StatusAccepted) return ctx, false, nil } - return nil, false, fmt.Errorf("couldn't get requesting account %s: %s", publicKeyOwnerURI, err) + err = fmt.Errorf("AuthenticatePostInbox: couldn't get requesting account %s: %w", publicKeyOwnerURI, err) + return nil, false, err } + // We have everything we need now, set the requesting + // and receiving accounts on the context for later use. withRequesting := context.WithValue(ctx, ap.ContextRequestingAccount, requestingAccount) withReceiving := context.WithValue(withRequesting, ap.ContextReceivingAccount, receivingAccount) return withReceiving, true, nil @@ -351,14 +359,15 @@ func (f *federator) Blocked(ctx context.Context, actorIRIs []*url.URL) (bool, er // type and extension. The unhandled ones are passed to DefaultCallback. func (f *federator) FederatingCallbacks(ctx context.Context) (wrapped pub.FederatingWrappedCallbacks, other []interface{}, err error) { wrapped = pub.FederatingWrappedCallbacks{ - // OnFollow determines what action to take for this particular callback - // if a Follow Activity is handled. + // OnFollow determines what action to take for this + // particular callback if a Follow Activity is handled. // - // For our implementation, we always want to do nothing because we have internal logic for handling follows. + // For our implementation, we always want to do nothing + // because we have internal logic for handling follows. OnFollow: pub.OnFollowDoNothing, } - // override some default behaviors and trigger our own side effects + // Override some default behaviors to trigger our own side effects. other = []interface{}{ func(ctx context.Context, undo vocab.ActivityStreamsUndo) error { return f.FederatingDB().Undo(ctx, undo) @@ -385,11 +394,7 @@ func (f *federator) FederatingCallbacks(ctx context.Context) (wrapped pub.Federa // type and extension, so the unhandled ones are passed to // DefaultCallback. func (f *federator) DefaultCallback(ctx context.Context, activity pub.Activity) error { - l := log.WithContext(ctx). - WithFields(kv.Fields{ - {"aptype", activity.GetTypeName()}, - }...) - l.Debug("received unhandle-able activity type so ignoring it") + log.Debugf(ctx, "received unhandle-able activity type (%s) so ignoring it", activity.GetTypeName()) return nil } diff --git a/internal/federation/handshake.go b/internal/federation/handshake.go deleted file mode 100644 index b83d2b6c4..000000000 --- a/internal/federation/handshake.go +++ /dev/null @@ -1,18 +0,0 @@ -// GoToSocial -// Copyright (C) GoToSocial Authors admin@gotosocial.org -// SPDX-License-Identifier: AGPL-3.0-or-later -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. - -package federation |