summaryrefslogtreecommitdiff
path: root/internal/federation/federatingdb
diff options
context:
space:
mode:
Diffstat (limited to 'internal/federation/federatingdb')
-rw-r--r--internal/federation/federatingdb/get.go73
1 files changed, 59 insertions, 14 deletions
diff --git a/internal/federation/federatingdb/get.go b/internal/federation/federatingdb/get.go
index 10e7dae8c..92c2d1d8d 100644
--- a/internal/federation/federatingdb/get.go
+++ b/internal/federation/federatingdb/get.go
@@ -19,10 +19,12 @@ package federatingdb
import (
"context"
- "fmt"
"net/url"
"code.superseriousbusiness.org/activity/streams/vocab"
+ "code.superseriousbusiness.org/gotosocial/internal/config"
+ "code.superseriousbusiness.org/gotosocial/internal/db"
+ "code.superseriousbusiness.org/gotosocial/internal/gtserror"
"code.superseriousbusiness.org/gotosocial/internal/log"
"code.superseriousbusiness.org/gotosocial/internal/uris"
)
@@ -30,35 +32,78 @@ import (
// Get returns the database entry for the specified id.
//
// The library makes this call only after acquiring a lock first.
+//
+// Implementation notes: in GoToSocial this function should *only*
+// be used for internal dereference calls. Everything coming from the
+// outside goes via the handlers defined in internal/api/activitypub.
+//
+// Normally with go-fed this function would get used in lots of
+// places for the side effect callback handlers, but since we override
+// everything and handle side effects ourselves, the only two places
+// this function actually ends up getting called are:
+//
+// - vendor/code.superseriousbusiness.org/activity/pub/side_effect_actor.go
+// to get outbox actor inside the prepare function.
+// - internal/transport/controller.go to try to shortcut deref a local item.
+//
+// It may be useful in future to add more matching here so that more
+// stuff can be shortcutted by the dereferencer, saving HTTP calls.
func (f *federatingDB) Get(ctx context.Context, id *url.URL) (value vocab.Type, err error) {
log.DebugKV(ctx, "id", id)
- switch {
+ // Ensure our host, for safety.
+ if id.Host != config.GetHost() {
+ return nil, gtserror.Newf("%s was not for our host", id.String())
+ }
- case uris.IsUserPath(id):
- acct, err := f.state.DB.GetAccountByURI(ctx, id.String())
+ if username, err := uris.ParseUserPath(id); err == nil && username != "" {
+ acct, err := f.state.DB.GetAccountByUsernameDomain(ctx, username, "")
if err != nil {
return nil, err
}
return f.converter.AccountToAS(ctx, acct)
- case uris.IsStatusesPath(id):
- status, err := f.state.DB.GetStatusByURI(ctx, id.String())
+ } else if _, statusID, err := uris.ParseStatusesPath(id); err == nil && statusID != "" {
+ status, err := f.state.DB.GetStatusByID(ctx, statusID)
if err != nil {
return nil, err
}
return f.converter.StatusToAS(ctx, status)
- case uris.IsFollowersPath(id):
- return f.Followers(ctx, id)
+ } else if username, err := uris.ParseFollowersPath(id); err == nil && username != "" {
+ acct, err := f.state.DB.GetAccountByUsernameDomain(ctx, username, "")
+ if err != nil {
+ return nil, err
+ }
- case uris.IsFollowingPath(id):
- return f.Following(ctx, id)
+ acctURI, err := url.Parse(acct.URI)
+ if err != nil {
+ return nil, err
+ }
- case uris.IsAcceptsPath(id):
- return f.GetAccept(ctx, id)
+ return f.Followers(ctx, acctURI)
- default:
- return nil, fmt.Errorf("federatingDB: could not Get %s", id.String())
+ } else if username, err := uris.ParseFollowingPath(id); err == nil && username != "" {
+ acct, err := f.state.DB.GetAccountByUsernameDomain(ctx, username, "")
+ if err != nil {
+ return nil, err
+ }
+
+ acctURI, err := url.Parse(acct.URI)
+ if err != nil {
+ return nil, err
+ }
+
+ return f.Following(ctx, acctURI)
+
+ } else if uris.IsAcceptsPath(id) {
+ return f.GetAccept(ctx, id)
}
+
+ // Nothing found, the caller
+ // will have to deal with this.
+ return nil, gtserror.Newf(
+ "not implemented for %s: %w",
+ id.String(), db.ErrNoEntries,
+ )
}