package oauth import ( "github.com/gin-gonic/gin" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" "github.com/superseriousbusiness/oauth2/v4" "github.com/superseriousbusiness/oauth2/v4/errors" ) // Auth wraps an authorized token, application, user, and account. // It is used in the functions GetAuthed and MustAuth. // Because the user might *not* be authed, any of the fields in this struct // might be nil, so make sure to check that when you're using this struct anywhere. type Auth struct { Token oauth2.TokenInfo Application *gtsmodel.Application User *gtsmodel.User Account *gtsmodel.Account } // Authed is a convenience function for returning an Authed struct from a gin context. // In essence, it tries to extract a token, application, user, and account from the context, // and then sets them on a struct for convenience. // // If any are not present in the context, they will be set to nil on the returned Authed struct. // // If *ALL* are not present, then nil and an error will be returned. // // If something goes wrong during parsing, then nil and an error will be returned (consider this not authed). // Authed is like GetAuthed, but will fail if one of the requirements is not met. func Authed(c *gin.Context, requireToken bool, requireApp bool, requireUser bool, requireAccount bool) (*Auth, error) { ctx := c.Copy() a := &Auth{} var i interface{} var ok bool i, ok = ctx.Get(SessionAuthorizedToken) if ok { parsed, ok := i.(oauth2.TokenInfo) if !ok { return nil, errors.New("could not parse token from session context") } a.Token = parsed } i, ok = ctx.Get(SessionAuthorizedApplication) if ok { parsed, ok := i.(*gtsmodel.Application) if !ok { return nil, errors.New("could not parse application from session context") } a.Application = parsed } i, ok = ctx.Get(SessionAuthorizedUser) if ok { parsed, ok := i.(*gtsmodel.User) if !ok { return nil, errors.New("could not parse user from session context") } a.User = parsed } i, ok = ctx.Get(SessionAuthorizedAccount) if ok { parsed, ok := i.(*gtsmodel.Account) if !ok { return nil, errors.New("could not parse account from session context") } a.Account = parsed } if requireToken && a.Token == nil { return nil, errors.New("token not supplied") } if requireApp && a.Application == nil { return nil, errors.New("application not supplied") } if requireUser { if a.User == nil { return nil, errors.New("user not supplied") } if a.User.Disabled || !a.User.Approved { return nil, errors.New("user disabled or not approved") } if a.User.Email == "" { return nil, errors.New("user has no confirmed email address") } } if requireAccount { if a.Account == nil { return nil, errors.New("account not supplied") } if !a.Account.SuspendedAt.IsZero() { return nil, errors.New("account suspended") } } return a, nil }