summaryrefslogtreecommitdiff
path: root/internal/apimodule/account
diff options
context:
space:
mode:
Diffstat (limited to 'internal/apimodule/account')
-rw-r--r--internal/apimodule/account/account.go47
-rw-r--r--internal/apimodule/account/accountcreate.go6
-rw-r--r--internal/apimodule/account/accountget.go6
-rw-r--r--internal/apimodule/account/accountupdate.go8
-rw-r--r--internal/apimodule/account/accountverify.go4
-rw-r--r--internal/apimodule/account/test/accountcreate_test.go (renamed from internal/apimodule/account/accountcreate_test.go)43
-rw-r--r--internal/apimodule/account/test/accountupdate_test.go (renamed from internal/apimodule/account/accountupdate_test.go)11
-rw-r--r--internal/apimodule/account/test/accountverify_test.go (renamed from internal/apimodule/account/accountverify_test.go)0
8 files changed, 67 insertions, 58 deletions
diff --git a/internal/apimodule/account/account.go b/internal/apimodule/account/account.go
index f4a47f6a2..a836afcdb 100644
--- a/internal/apimodule/account/account.go
+++ b/internal/apimodule/account/account.go
@@ -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)
}
}
}
diff --git a/internal/apimodule/account/accountcreate.go b/internal/apimodule/account/accountcreate.go
index 266d820af..fb21925b8 100644
--- a/internal/apimodule/account/accountcreate.go
+++ b/internal/apimodule/account/accountcreate.go
@@ -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
diff --git a/internal/apimodule/account/accountget.go b/internal/apimodule/account/accountget.go
index cd4aed22e..5003be139 100644
--- a/internal/apimodule/account/accountget.go
+++ b/internal/apimodule/account/accountget.go
@@ -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
diff --git a/internal/apimodule/account/accountupdate.go b/internal/apimodule/account/accountupdate.go
index 15e9cf0d1..7709697bf 100644
--- a/internal/apimodule/account/accountupdate.go
+++ b/internal/apimodule/account/accountupdate.go
@@ -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)
diff --git a/internal/apimodule/account/accountverify.go b/internal/apimodule/account/accountverify.go
index 584ab6122..9edf1e73a 100644
--- a/internal/apimodule/account/accountverify.go
+++ b/internal/apimodule/account/accountverify.go
@@ -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 {
diff --git a/internal/apimodule/account/accountcreate_test.go b/internal/apimodule/account/test/accountcreate_test.go
index 8677e3573..81eab467a 100644
--- a/internal/apimodule/account/accountcreate_test.go
+++ b/internal/apimodule/account/test/accountcreate_test.go
@@ -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
diff --git a/internal/apimodule/account/accountupdate_test.go b/internal/apimodule/account/test/accountupdate_test.go
index 7ca2190d8..1c6f528a1 100644
--- a/internal/apimodule/account/accountupdate_test.go
+++ b/internal/apimodule/account/test/accountupdate_test.go
@@ -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
diff --git a/internal/apimodule/account/accountverify_test.go b/internal/apimodule/account/test/accountverify_test.go
index 223a0c145..223a0c145 100644
--- a/internal/apimodule/account/accountverify_test.go
+++ b/internal/apimodule/account/test/accountverify_test.go