diff --git a/internal/federation/common.go b/internal/federation/common.go index 0c73a8bf4..92cd962eb 100644 --- a/internal/federation/common.go +++ b/internal/federation/common.go @@ -20,16 +20,19 @@ package federation import ( "context" + "errors" "fmt" "net/http" "net/url" + "github.com/gin-gonic/gin" "github.com/go-fed/activity/pub" "github.com/go-fed/activity/streams/vocab" "github.com/sirupsen/logrus" "github.com/superseriousbusiness/gotosocial/internal/config" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/db/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/oauth" "github.com/superseriousbusiness/gotosocial/internal/transport" "github.com/superseriousbusiness/gotosocial/internal/util" ) @@ -79,8 +82,44 @@ func NewCommonBehavior(db db.DB, log *logrus.Logger, config *config.Config, tran // authenticated must be true and error nil. The request will continue // to be processed. func (c *commonBehavior) AuthenticateGetInbox(ctx context.Context, w http.ResponseWriter, r *http.Request) (context.Context, bool, error) { - // TODO - // use context.WithValue() and context.Value() to set and get values through here + l := c.log.WithFields(logrus.Fields{ + "func": "AuthenticateGetInbox", + "url": r.URL.String(), + }) + + if !util.IsInboxPath(r.URL) { + err := errors.New("url %s was not for an inbox", r.URL.String()) + } + + // Earlier in the chain before this function was called, we set a *copy* of the *gin.Context as a value on the context.Context, + // this means that we can retrieve that and use it to check whether we're authorized or not. + + // retrieve what should be a copy of a *gin.Context from the context.Context + gctxI := ctx.Value(util.GinContextKey) + if gctxI == nil { + err := errors.New("AuthenticateGetInbox: nothing was set on the gincontext key of context.Context") + l.Error(err) + return nil, false, err + } + + // cast it to what is hopefully a *gin.Context + gctx, ok := gctxI.(*gin.Context) + if !ok { + err := errors.New("AuthenticateGetInbox: something was set on context.Context but it wasn't a *gin.Context") + l.Error(err) + return nil, false, err + } + + authed, err := oauth.MustAuth(gctx, true, false, true, true) // we need a token, user, and account to be considered 'authed' + if err != nil { + // whatever happened, we're not authorized -- we don't care so much about an error at this point so just log it and move on + l.Debugf("not authed: %s", err) + return ctx, false, nil + } + + // we need the check now that the authed user is the same as the user that the inbox belongs to + + return nil, false, nil } diff --git a/internal/util/uri.go b/internal/util/uri.go index 444d14e6a..e99fa7762 100644 --- a/internal/util/uri.go +++ b/internal/util/uri.go @@ -63,6 +63,10 @@ const ( APRequestingAccountKey APContextKey = "requestingAccount" ) +type ginContextKey struct{} +// GinContextKey is used solely for setting and retrieving the gin context from a context.Context +var GinContextKey = &ginContextKey{} + // UserURIs contains a bunch of UserURIs and URLs for a user, host, account, etc. type UserURIs struct { // The web URL of the instance host, eg https://example.org