groundwork for other account routes

This commit is contained in:
tsmethurst 2021-03-24 17:34:41 +01:00
commit 26c482cd86
9 changed files with 186 additions and 65 deletions

View file

@ -19,7 +19,6 @@
package account
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
@ -29,6 +28,7 @@ import (
"github.com/gotosocial/gotosocial/internal/module"
"github.com/gotosocial/gotosocial/internal/module/oauth"
"github.com/gotosocial/gotosocial/internal/router"
"github.com/sirupsen/logrus"
)
const (
@ -40,49 +40,62 @@ const (
type accountModule struct {
config *config.Config
db db.DB
log *logrus.Logger
}
// New returns a new account module
func New(config *config.Config, db db.DB) module.ClientAPIModule {
func New(config *config.Config, db db.DB, log *logrus.Logger) module.ClientAPIModule {
return &accountModule{
config: config,
db: db,
log: log,
}
}
// Route attaches all routes from this module to the given router
func (m *accountModule) Route(r router.Router) error {
r.AttachHandler(http.MethodPost, basePath, m.AccountCreatePOSTHandler)
r.AttachHandler(http.MethodGet, verifyPath, m.AccountVerifyGETHandler)
return nil
}
func (m *accountModule) AccountCreatePOSTHandler(c *gin.Context) {
l := m.log.WithField("func", "AccountCreatePOSTHandler")
l.Trace("checking if registration is open")
if !m.config.AccountsConfig.OpenRegistration {
l.Trace("account registration is closed, returning error to client")
}
}
// AccountVerifyGETHandler serves a user's account details to them IF they reached this
// handler while in possession of a valid token, according to the oauth middleware.
func (m *accountModule) AccountVerifyGETHandler(c *gin.Context) {
i, ok := c.Get(oauth.SessionAuthorizedUser)
fmt.Println(i)
l := m.log.WithField("func", "AccountVerifyGETHandler")
l.Trace("getting account details from session")
i, ok := c.Get(oauth.SessionAuthorizedAccount)
if !ok {
l.Trace("no account in session, returning error to client")
c.JSON(http.StatusUnauthorized, gin.H{"error": "The access token is invalid"})
return
}
userID, ok := (i).(string)
if !ok || userID == "" {
l.Trace("attempting to convert account interface into account struct...")
acct, ok := i.(*model.Account)
if !ok {
l.Tracef("could not convert %+v into account struct, returning error to client", i)
c.JSON(http.StatusUnauthorized, gin.H{"error": "The access token is invalid"})
return
}
acct := &model.Account{}
if err := m.db.GetAccountByUserID(userID, acct); err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
l.Tracef("retrieved account %+v, converting to mastosensitive...", acct)
acctSensitive, err := m.db.AccountToMastoSensitive(acct)
if err != nil {
l.Tracef("could not convert account into mastosensitive account: %s", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
l.Tracef("conversion successful, returning OK and mastosensitive account %+v", acctSensitive)
c.JSON(http.StatusOK, acctSensitive)
}

View file

@ -216,10 +216,19 @@ func (suite *AccountTestSuite) TestAPIInitialize() {
}
r.AttachMiddleware(func(c *gin.Context) {
account := &model.Account{}
if err := suite.db.GetAccountByUserID(suite.testUser.ID, account); err != nil || account == nil {
suite.T().Log(err)
suite.FailNowf("no account found for user %s, continuing with unauthenticated request: %+v", "", suite.testUser.ID, account)
fmt.Println(account)
return
}
c.Set(oauth.SessionAuthorizedAccount, account)
c.Set(oauth.SessionAuthorizedUser, suite.testUser.ID)
})
acct := New(suite.config, suite.db)
acct := New(suite.config, suite.db, log)
acct.Route(r)
r.Start()

View file

@ -47,11 +47,12 @@ import (
)
const (
appsPath = "/api/v1/apps"
authSignInPath = "/auth/sign_in"
oauthTokenPath = "/oauth/token"
oauthAuthorizePath = "/oauth/authorize"
SessionAuthorizedUser = "authorized_user"
appsPath = "/api/v1/apps"
authSignInPath = "/auth/sign_in"
oauthTokenPath = "/oauth/token"
oauthAuthorizePath = "/oauth/authorize"
SessionAuthorizedUser = "authorized_user"
SessionAuthorizedAccount = "authorized_account"
)
// oauthModule is an oauth2 oauthModule that satisfies the ClientAPIModule interface
@ -406,16 +407,30 @@ func (m *oauthModule) authorizePOSTHandler(c *gin.Context) {
MIDDLEWARE
*/
// oauthTokenMiddleware
// oauthTokenMiddleware checks if the client has presented a valid oauth Bearer token.
// If so, it will check the User that the token belongs to, and set that in the context of
// the request. Then, it will look up the account for that user, and set that in the request too.
// If user or account can't be found, then the handler won't *fail*, in case the server wants to allow
// public requests that don't have a Bearer token set (eg., for public instance information and so on).
func (m *oauthModule) oauthTokenMiddleware(c *gin.Context) {
l := m.log.WithField("func", "ValidatePassword")
l.Trace("entering OauthTokenMiddleware")
if ti, err := m.oauthServer.ValidationBearerToken(c.Request); err == nil {
l.Tracef("authenticated user %s with bearer token, scope is %s", ti.GetUserID(), ti.GetScope())
c.Set(SessionAuthorizedUser, ti.GetUserID())
} else {
l.Trace("continuing with unauthenticated request")
ti, err := m.oauthServer.ValidationBearerToken(c.Request)
if err != nil {
l.Trace("no valid token presented: continuing with unauthenticated request")
return
}
l.Tracef("authenticated user %s with bearer token, scope is %s", ti.GetUserID(), ti.GetScope())
acct := &model.Account{}
if err := m.db.GetAccountByUserID(ti.GetUserID(), acct); err != nil || acct == nil {
l.Tracef("no account found for user %s, continuing with unauthenticated request", ti.GetUserID())
return
}
c.Set(SessionAuthorizedAccount, acct)
c.Set(SessionAuthorizedUser, ti.GetUserID())
}
/*