linting + organizing

This commit is contained in:
tsmethurst
2021-04-20 18:14:23 +02:00
parent 32c5fd987a
commit dafc3b5b92
60 changed files with 746 additions and 390 deletions

View File

@ -37,25 +37,31 @@ import (
)
const (
idKey = "id"
basePath = "/api/v1/accounts"
basePathWithID = basePath + "/:" + idKey
verifyPath = basePath + "/verify_credentials"
updateCredentialsPath = basePath + "/update_credentials"
// IDKey is the key to use for retrieving account ID in requests
IDKey = "id"
// BasePath is the base API path for this module
BasePath = "/api/v1/accounts"
// BasePathWithID is the base path for this module with the ID key
BasePathWithID = BasePath + "/:" + IDKey
// VerifyPath is for verifying account credentials
VerifyPath = BasePath + "/verify_credentials"
// UpdateCredentialsPath is for updating account credentials
UpdateCredentialsPath = BasePath + "/update_credentials"
)
type accountModule struct {
// Module implements the ClientAPIModule interface for account-related actions
type Module struct {
config *config.Config
db db.DB
oauthServer oauth.Server
mediaHandler media.MediaHandler
mediaHandler media.Handler
mastoConverter mastotypes.Converter
log *logrus.Logger
}
// New returns a new account module
func New(config *config.Config, db db.DB, oauthServer oauth.Server, mediaHandler media.MediaHandler, mastoConverter mastotypes.Converter, log *logrus.Logger) apimodule.ClientAPIModule {
return &accountModule{
func New(config *config.Config, db db.DB, oauthServer oauth.Server, mediaHandler media.Handler, mastoConverter mastotypes.Converter, log *logrus.Logger) apimodule.ClientAPIModule {
return &Module{
config: config,
db: db,
oauthServer: oauthServer,
@ -66,14 +72,15 @@ func New(config *config.Config, db db.DB, oauthServer oauth.Server, mediaHandler
}
// 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, basePathWithID, m.muxHandler)
r.AttachHandler(http.MethodPatch, basePathWithID, m.muxHandler)
func (m *Module) Route(r router.Router) error {
r.AttachHandler(http.MethodPost, BasePath, m.AccountCreatePOSTHandler)
r.AttachHandler(http.MethodGet, BasePathWithID, m.muxHandler)
r.AttachHandler(http.MethodPatch, BasePathWithID, m.muxHandler)
return nil
}
func (m *accountModule) CreateTables(db db.DB) error {
// CreateTables creates the required tables for this module in the given database
func (m *Module) CreateTables(db db.DB) error {
models := []interface{}{
&gtsmodel.User{},
&gtsmodel.Account{},
@ -93,18 +100,18 @@ func (m *accountModule) CreateTables(db db.DB) error {
return nil
}
func (m *accountModule) muxHandler(c *gin.Context) {
func (m *Module) muxHandler(c *gin.Context) {
ru := c.Request.RequestURI
switch c.Request.Method {
case http.MethodGet:
if strings.HasPrefix(ru, verifyPath) {
m.accountVerifyGETHandler(c)
if strings.HasPrefix(ru, VerifyPath) {
m.AccountVerifyGETHandler(c)
} else {
m.accountGETHandler(c)
m.AccountGETHandler(c)
}
case http.MethodPatch:
if strings.HasPrefix(ru, updateCredentialsPath) {
m.accountUpdateCredentialsPATCHHandler(c)
if strings.HasPrefix(ru, UpdateCredentialsPath) {
m.AccountUpdateCredentialsPATCHHandler(c)
}
}
}

View File

@ -34,10 +34,10 @@ import (
"github.com/superseriousbusiness/oauth2/v4"
)
// accountCreatePOSTHandler handles create account requests, validates them,
// AccountCreatePOSTHandler handles create account requests, validates them,
// and puts them in the database if they're valid.
// It should be served as a POST at /api/v1/accounts
func (m *accountModule) accountCreatePOSTHandler(c *gin.Context) {
func (m *Module) AccountCreatePOSTHandler(c *gin.Context) {
l := m.log.WithField("func", "accountCreatePOSTHandler")
authed, err := oauth.MustAuth(c, true, true, false, false)
if err != nil {
@ -83,7 +83,7 @@ func (m *accountModule) accountCreatePOSTHandler(c *gin.Context) {
// accountCreate does the dirty work of making an account and user in the database.
// It then returns a token to the caller, for use with the new account, as per the
// spec here: https://docs.joinmastodon.org/methods/accounts/
func (m *accountModule) accountCreate(form *mastotypes.AccountCreateRequest, signUpIP net.IP, token oauth2.TokenInfo, app *gtsmodel.Application) (*mastotypes.Token, error) {
func (m *Module) accountCreate(form *mastotypes.AccountCreateRequest, signUpIP net.IP, token oauth2.TokenInfo, app *gtsmodel.Application) (*mastotypes.Token, error) {
l := m.log.WithField("func", "accountCreate")
// don't store a reason if we don't require one

View File

@ -26,12 +26,12 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/db/gtsmodel"
)
// accountGetHandler serves the account information held by the server in response to a GET
// AccountGETHandler serves the account information held by the server in response to a GET
// request. It should be served as a GET at /api/v1/accounts/:id.
//
// See: https://docs.joinmastodon.org/methods/accounts/
func (m *accountModule) accountGETHandler(c *gin.Context) {
targetAcctID := c.Param(idKey)
func (m *Module) AccountGETHandler(c *gin.Context) {
targetAcctID := c.Param(IDKey)
if targetAcctID == "" {
c.JSON(http.StatusBadRequest, gin.H{"error": "no account id specified"})
return

View File

@ -34,7 +34,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/util"
)
// accountUpdateCredentialsPATCHHandler allows a user to modify their account/profile settings.
// AccountUpdateCredentialsPATCHHandler allows a user to modify their account/profile settings.
// It should be served as a PATCH at /api/v1/accounts/update_credentials
//
// TODO: this can be optimized massively by building up a picture of what we want the new account
@ -42,7 +42,7 @@ import (
// which is not gonna make the database very happy when lots of requests are going through.
// This way it would also be safer because the update won't happen until *all* the fields are validated.
// Otherwise we risk doing a partial update and that's gonna cause probllleeemmmsss.
func (m *accountModule) accountUpdateCredentialsPATCHHandler(c *gin.Context) {
func (m *Module) AccountUpdateCredentialsPATCHHandler(c *gin.Context) {
l := m.log.WithField("func", "accountUpdateCredentialsPATCHHandler")
authed, err := oauth.MustAuth(c, true, false, false, true)
if err != nil {
@ -196,7 +196,7 @@ func (m *accountModule) accountUpdateCredentialsPATCHHandler(c *gin.Context) {
// UpdateAccountAvatar does the dirty work of checking the avatar part of an account update form,
// parsing and checking the image, and doing the necessary updates in the database for this to become
// the account's new avatar image.
func (m *accountModule) UpdateAccountAvatar(avatar *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) {
func (m *Module) UpdateAccountAvatar(avatar *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) {
var err error
if int(avatar.Size) > m.config.MediaConfig.MaxImageSize {
err = fmt.Errorf("avatar with size %d exceeded max image size of %d bytes", avatar.Size, m.config.MediaConfig.MaxImageSize)
@ -229,7 +229,7 @@ func (m *accountModule) UpdateAccountAvatar(avatar *multipart.FileHeader, accoun
// UpdateAccountHeader does the dirty work of checking the header part of an account update form,
// parsing and checking the image, and doing the necessary updates in the database for this to become
// the account's new header image.
func (m *accountModule) UpdateAccountHeader(header *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) {
func (m *Module) UpdateAccountHeader(header *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) {
var err error
if int(header.Size) > m.config.MediaConfig.MaxImageSize {
err = fmt.Errorf("header with size %d exceeded max image size of %d bytes", header.Size, m.config.MediaConfig.MaxImageSize)

View File

@ -25,10 +25,10 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)
// accountVerifyGETHandler serves a user's account details to them IF they reached this
// 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.
// It should be served as a GET at /api/v1/accounts/verify_credentials
func (m *accountModule) accountVerifyGETHandler(c *gin.Context) {
func (m *Module) AccountVerifyGETHandler(c *gin.Context) {
l := m.log.WithField("func", "accountVerifyGETHandler")
authed, err := oauth.MustAuth(c, true, false, false, true)
if err != nil {

View File

@ -39,6 +39,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/apimodule/account"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/db/gtsmodel"
@ -63,10 +64,10 @@ type AccountCreateTestSuite struct {
testToken oauth2.TokenInfo
mockOauthServer *oauth.MockServer
mockStorage *storage.MockStorage
mediaHandler media.MediaHandler
mediaHandler media.Handler
mastoConverter mastotypes.Converter
db db.DB
accountModule *accountModule
accountModule *account.Module
newUserFormHappyPath url.Values
}
@ -164,7 +165,7 @@ func (suite *AccountCreateTestSuite) SetupSuite() {
suite.mastoConverter = mastotypes.New(suite.config, suite.db)
// and finally here's the thing we're actually testing!
suite.accountModule = New(suite.config, suite.db, suite.mockOauthServer, suite.mediaHandler, suite.mastoConverter, suite.log).(*accountModule)
suite.accountModule = account.New(suite.config, suite.db, suite.mockOauthServer, suite.mediaHandler, suite.mastoConverter, suite.log).(*account.Module)
}
func (suite *AccountCreateTestSuite) TearDownSuite() {
@ -250,9 +251,9 @@ func (suite *AccountCreateTestSuite) TestAccountCreatePOSTHandlerSuccessful() {
ctx, _ := gin.CreateTestContext(recorder)
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplication)
ctx.Set(oauth.SessionAuthorizedToken, suite.testToken)
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), nil) // the endpoint we're hitting
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", account.BasePath), nil) // the endpoint we're hitting
ctx.Request.Form = suite.newUserFormHappyPath
suite.accountModule.accountCreatePOSTHandler(ctx)
suite.accountModule.AccountCreatePOSTHandler(ctx)
// check response
@ -324,9 +325,9 @@ func (suite *AccountCreateTestSuite) TestAccountCreatePOSTHandlerNoAuth() {
// setup
recorder := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(recorder)
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), nil) // the endpoint we're hitting
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", account.BasePath), nil) // the endpoint we're hitting
ctx.Request.Form = suite.newUserFormHappyPath
suite.accountModule.accountCreatePOSTHandler(ctx)
suite.accountModule.AccountCreatePOSTHandler(ctx)
// check response
@ -349,8 +350,8 @@ func (suite *AccountCreateTestSuite) TestAccountCreatePOSTHandlerNoForm() {
ctx, _ := gin.CreateTestContext(recorder)
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplication)
ctx.Set(oauth.SessionAuthorizedToken, suite.testToken)
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), nil) // the endpoint we're hitting
suite.accountModule.accountCreatePOSTHandler(ctx)
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", account.BasePath), nil) // the endpoint we're hitting
suite.accountModule.AccountCreatePOSTHandler(ctx)
// check response
suite.EqualValues(http.StatusBadRequest, recorder.Code)
@ -371,11 +372,11 @@ func (suite *AccountCreateTestSuite) TestAccountCreatePOSTHandlerWeakPassword()
ctx, _ := gin.CreateTestContext(recorder)
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplication)
ctx.Set(oauth.SessionAuthorizedToken, suite.testToken)
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), nil) // the endpoint we're hitting
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", account.BasePath), nil) // the endpoint we're hitting
ctx.Request.Form = suite.newUserFormHappyPath
// set a weak password
ctx.Request.Form.Set("password", "weak")
suite.accountModule.accountCreatePOSTHandler(ctx)
suite.accountModule.AccountCreatePOSTHandler(ctx)
// check response
suite.EqualValues(http.StatusBadRequest, recorder.Code)
@ -396,11 +397,11 @@ func (suite *AccountCreateTestSuite) TestAccountCreatePOSTHandlerWeirdLocale() {
ctx, _ := gin.CreateTestContext(recorder)
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplication)
ctx.Set(oauth.SessionAuthorizedToken, suite.testToken)
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), nil) // the endpoint we're hitting
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", account.BasePath), nil) // the endpoint we're hitting
ctx.Request.Form = suite.newUserFormHappyPath
// set an invalid locale
ctx.Request.Form.Set("locale", "neverneverland")
suite.accountModule.accountCreatePOSTHandler(ctx)
suite.accountModule.AccountCreatePOSTHandler(ctx)
// check response
suite.EqualValues(http.StatusBadRequest, recorder.Code)
@ -421,12 +422,12 @@ func (suite *AccountCreateTestSuite) TestAccountCreatePOSTHandlerRegistrationsCl
ctx, _ := gin.CreateTestContext(recorder)
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplication)
ctx.Set(oauth.SessionAuthorizedToken, suite.testToken)
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), nil) // the endpoint we're hitting
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", account.BasePath), nil) // the endpoint we're hitting
ctx.Request.Form = suite.newUserFormHappyPath
// close registrations
suite.config.AccountsConfig.OpenRegistration = false
suite.accountModule.accountCreatePOSTHandler(ctx)
suite.accountModule.AccountCreatePOSTHandler(ctx)
// check response
suite.EqualValues(http.StatusBadRequest, recorder.Code)
@ -447,13 +448,13 @@ func (suite *AccountCreateTestSuite) TestAccountCreatePOSTHandlerReasonNotProvid
ctx, _ := gin.CreateTestContext(recorder)
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplication)
ctx.Set(oauth.SessionAuthorizedToken, suite.testToken)
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), nil) // the endpoint we're hitting
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", account.BasePath), nil) // the endpoint we're hitting
ctx.Request.Form = suite.newUserFormHappyPath
// remove reason
ctx.Request.Form.Set("reason", "")
suite.accountModule.accountCreatePOSTHandler(ctx)
suite.accountModule.AccountCreatePOSTHandler(ctx)
// check response
suite.EqualValues(http.StatusBadRequest, recorder.Code)
@ -474,13 +475,13 @@ func (suite *AccountCreateTestSuite) TestAccountCreatePOSTHandlerInsufficientRea
ctx, _ := gin.CreateTestContext(recorder)
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplication)
ctx.Set(oauth.SessionAuthorizedToken, suite.testToken)
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", basePath), nil) // the endpoint we're hitting
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", account.BasePath), nil) // the endpoint we're hitting
ctx.Request.Form = suite.newUserFormHappyPath
// remove reason
ctx.Request.Form.Set("reason", "just cuz")
suite.accountModule.accountCreatePOSTHandler(ctx)
suite.accountModule.AccountCreatePOSTHandler(ctx)
// check response
suite.EqualValues(http.StatusBadRequest, recorder.Code)
@ -526,9 +527,9 @@ func (suite *AccountCreateTestSuite) TestAccountUpdateCredentialsPATCHHandler()
ctx, _ := gin.CreateTestContext(recorder)
ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccountLocal)
ctx.Set(oauth.SessionAuthorizedToken, suite.testToken)
ctx.Request = httptest.NewRequest(http.MethodPatch, fmt.Sprintf("http://localhost:8080/%s", updateCredentialsPath), body) // the endpoint we're hitting
ctx.Request = httptest.NewRequest(http.MethodPatch, fmt.Sprintf("http://localhost:8080/%s", account.UpdateCredentialsPath), body) // the endpoint we're hitting
ctx.Request.Header.Set("Content-Type", writer.FormDataContentType())
suite.accountModule.accountUpdateCredentialsPATCHHandler(ctx)
suite.accountModule.AccountUpdateCredentialsPATCHHandler(ctx)
// check response

View File

@ -37,6 +37,7 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/apimodule/account"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/db/gtsmodel"
@ -58,10 +59,10 @@ type AccountUpdateTestSuite struct {
testToken oauth2.TokenInfo
mockOauthServer *oauth.MockServer
mockStorage *storage.MockStorage
mediaHandler media.MediaHandler
mediaHandler media.Handler
mastoConverter mastotypes.Converter
db db.DB
accountModule *accountModule
accountModule *account.Module
newUserFormHappyPath url.Values
}
@ -159,7 +160,7 @@ func (suite *AccountUpdateTestSuite) SetupSuite() {
suite.mastoConverter = mastotypes.New(suite.config, suite.db)
// and finally here's the thing we're actually testing!
suite.accountModule = New(suite.config, suite.db, suite.mockOauthServer, suite.mediaHandler, suite.mastoConverter, suite.log).(*accountModule)
suite.accountModule = account.New(suite.config, suite.db, suite.mockOauthServer, suite.mediaHandler, suite.mastoConverter, suite.log).(*account.Module)
}
func (suite *AccountUpdateTestSuite) TearDownSuite() {
@ -278,9 +279,9 @@ func (suite *AccountUpdateTestSuite) TestAccountUpdateCredentialsPATCHHandler()
ctx, _ := gin.CreateTestContext(recorder)
ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccountLocal)
ctx.Set(oauth.SessionAuthorizedToken, suite.testToken)
ctx.Request = httptest.NewRequest(http.MethodPatch, fmt.Sprintf("http://localhost:8080/%s", updateCredentialsPath), body) // the endpoint we're hitting
ctx.Request = httptest.NewRequest(http.MethodPatch, fmt.Sprintf("http://localhost:8080/%s", account.UpdateCredentialsPath), body) // the endpoint we're hitting
ctx.Request.Header.Set("Content-Type", writer.FormDataContentType())
suite.accountModule.accountUpdateCredentialsPATCHHandler(ctx)
suite.accountModule.AccountUpdateCredentialsPATCHHandler(ctx)
// check response