mirror of
https://github.com/superseriousbusiness/gotosocial
synced 2025-06-05 21:59:39 +02:00
Implement Cobra CLI tooling, Viper config tooling (#336)
* start pulling out + replacing urfave and config * replace many many instances of config * move more stuff => viper * properly remove urfave * move some flags to root command * add testrig commands to root * alias config file keys * start adding cli parsing tests * reorder viper init * remove config path alias * fmt * change config file keys to non-nested * we're more or less in business now * tidy up the common func * go fmt * get tests passing again * add note about the cliparsing tests * reorganize * update docs with changes * structure cmd dir better * rename + move some files around * fix dangling comma
This commit is contained in:
@@ -24,7 +24,6 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
@@ -76,14 +75,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for account-related actions
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new account module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"codeberg.org/gruf/go-store/kv"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/client/account"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
@@ -24,7 +25,6 @@ import (
|
||||
type AccountStandardTestSuite struct {
|
||||
// standard suite interfaces
|
||||
suite.Suite
|
||||
config *config.Config
|
||||
db db.DB
|
||||
tc typeutils.TypeConverter
|
||||
storage *kv.KVStore
|
||||
@@ -57,7 +57,7 @@ func (suite *AccountStandardTestSuite) SetupSuite() {
|
||||
}
|
||||
|
||||
func (suite *AccountStandardTestSuite) SetupTest() {
|
||||
suite.config = testrig.NewTestConfig()
|
||||
testrig.InitTestConfig()
|
||||
suite.db = testrig.NewTestDB()
|
||||
suite.storage = testrig.NewTestStorage()
|
||||
testrig.InitTestLog()
|
||||
@@ -65,7 +65,7 @@ func (suite *AccountStandardTestSuite) SetupTest() {
|
||||
suite.sentEmails = make(map[string]string)
|
||||
suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails)
|
||||
suite.processor = testrig.NewTestProcessor(suite.db, suite.storage, suite.federator, suite.emailSender)
|
||||
suite.accountModule = account.New(suite.config, suite.processor).(*account.Module)
|
||||
suite.accountModule = account.New(suite.processor).(*account.Module)
|
||||
testrig.StandardDBSetup(suite.db, nil)
|
||||
testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media")
|
||||
}
|
||||
@@ -83,7 +83,10 @@ func (suite *AccountStandardTestSuite) newContext(recorder *httptest.ResponseRec
|
||||
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
|
||||
ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"])
|
||||
|
||||
baseURI := fmt.Sprintf("%s://%s", suite.config.Protocol, suite.config.Host)
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
|
||||
baseURI := fmt.Sprintf("%s://%s", protocol, host)
|
||||
requestURI := fmt.Sprintf("%s/%s", baseURI, requestPath)
|
||||
|
||||
ctx.Request = httptest.NewRequest(http.MethodPatch, requestURI, bytes.NewReader(requestBody)) // the endpoint we're hitting
|
||||
|
@@ -20,10 +20,12 @@ package account
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
@@ -85,7 +87,7 @@ func (m *Module) AccountCreatePOSTHandler(c *gin.Context) {
|
||||
}
|
||||
|
||||
l.Tracef("validating form %+v", form)
|
||||
if err := validateCreateAccount(form, m.config.AccountsConfig); err != nil {
|
||||
if err := validateCreateAccount(form); err != nil {
|
||||
l.Debugf("error validating form: %s", err)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -114,8 +116,10 @@ func (m *Module) AccountCreatePOSTHandler(c *gin.Context) {
|
||||
|
||||
// validateCreateAccount checks through all the necessary prerequisites for creating a new account,
|
||||
// according to the provided account create request. If the account isn't eligible, an error will be returned.
|
||||
func validateCreateAccount(form *model.AccountCreateRequest, c *config.AccountsConfig) error {
|
||||
if !c.OpenRegistration {
|
||||
func validateCreateAccount(form *model.AccountCreateRequest) error {
|
||||
keys := config.Keys
|
||||
|
||||
if !viper.GetBool(keys.AccountsRegistrationOpen) {
|
||||
return errors.New("registration is not open for this server")
|
||||
}
|
||||
|
||||
@@ -139,7 +143,7 @@ func validateCreateAccount(form *model.AccountCreateRequest, c *config.AccountsC
|
||||
return err
|
||||
}
|
||||
|
||||
if err := validate.SignUpReason(form.Reason, c.ReasonRequired); err != nil {
|
||||
if err := validate.SignUpReason(form.Reason, viper.GetBool(keys.AccountsReasonRequired)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -47,14 +46,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for admin-related actions (reports, emojis, etc)
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new admin module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -32,14 +31,12 @@ const BasePath = "/api/v1/apps"
|
||||
|
||||
// Module implements the ClientAPIModule interface for requests relating to registering/removing applications
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new auth module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oidc"
|
||||
@@ -54,16 +53,14 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
db db.DB
|
||||
server oauth.Server
|
||||
idp oidc.IDP
|
||||
}
|
||||
|
||||
// New returns a new auth module
|
||||
func New(config *config.Config, db db.DB, server oauth.Server, idp oidc.IDP) api.ClientModule {
|
||||
func New(db db.DB, server oauth.Server, idp oidc.IDP) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
db: db,
|
||||
server: server,
|
||||
idp: idp,
|
||||
|
@@ -18,134 +18,4 @@
|
||||
|
||||
package auth_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db/bundb"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type AuthTestSuite struct {
|
||||
suite.Suite
|
||||
oauthServer oauth.Server
|
||||
db db.DB
|
||||
testAccount *gtsmodel.Account
|
||||
testApplication *gtsmodel.Application
|
||||
testUser *gtsmodel.User
|
||||
testClient *gtsmodel.Client
|
||||
config *config.Config
|
||||
}
|
||||
|
||||
// SetupSuite sets some variables on the suite that we can use as consts (more or less) throughout
|
||||
func (suite *AuthTestSuite) SetupSuite() {
|
||||
c := config.Default()
|
||||
// we're running on localhost without https so set the protocol to http
|
||||
c.Protocol = "http"
|
||||
// just for testing
|
||||
c.Host = "localhost:8080"
|
||||
// because go tests are run within the test package directory, we need to fiddle with the templateconfig
|
||||
// basedir in a way that we wouldn't normally have to do when running the binary, in order to make
|
||||
// the templates actually load
|
||||
c.TemplateConfig.BaseDir = "../../../web/template/"
|
||||
c.DBConfig = &config.DBConfig{
|
||||
Type: "postgres",
|
||||
Address: "localhost",
|
||||
Port: 5432,
|
||||
User: "postgres",
|
||||
Password: "postgres",
|
||||
Database: "postgres",
|
||||
ApplicationName: "gotosocial",
|
||||
}
|
||||
suite.config = c
|
||||
|
||||
encryptedPassword, err := bcrypt.GenerateFromPassword([]byte("password"), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
logrus.Panicf("error encrypting user pass: %s", err)
|
||||
}
|
||||
|
||||
acctID := uuid.NewString()
|
||||
|
||||
suite.testAccount = >smodel.Account{
|
||||
ID: acctID,
|
||||
Username: "test_user",
|
||||
}
|
||||
suite.testUser = >smodel.User{
|
||||
EncryptedPassword: string(encryptedPassword),
|
||||
Email: "user@example.org",
|
||||
AccountID: acctID,
|
||||
}
|
||||
suite.testClient = >smodel.Client{
|
||||
ID: "a-known-client-id",
|
||||
Secret: "some-secret",
|
||||
Domain: fmt.Sprintf("%s://%s", c.Protocol, c.Host),
|
||||
}
|
||||
suite.testApplication = >smodel.Application{
|
||||
Name: "a test application",
|
||||
Website: "https://some-application-website.com",
|
||||
RedirectURI: "http://localhost:8080",
|
||||
ClientID: "a-known-client-id",
|
||||
ClientSecret: "some-secret",
|
||||
Scopes: "read",
|
||||
}
|
||||
}
|
||||
|
||||
// SetupTest creates a postgres connection and creates the oauth_clients table before each test
|
||||
func (suite *AuthTestSuite) SetupTest() {
|
||||
|
||||
log := logrus.New()
|
||||
log.SetLevel(logrus.TraceLevel)
|
||||
db, err := bundb.NewBunDBService(context.Background(), suite.config)
|
||||
if err != nil {
|
||||
logrus.Panicf("error creating database connection: %s", err)
|
||||
}
|
||||
|
||||
suite.db = db
|
||||
suite.oauthServer = oauth.New(context.Background(), suite.db)
|
||||
|
||||
if err := suite.db.Put(context.Background(), suite.testAccount); err != nil {
|
||||
logrus.Panicf("could not insert test account into db: %s", err)
|
||||
}
|
||||
if err := suite.db.Put(context.Background(), suite.testUser); err != nil {
|
||||
logrus.Panicf("could not insert test user into db: %s", err)
|
||||
}
|
||||
if err := suite.db.Put(context.Background(), suite.testClient); err != nil {
|
||||
logrus.Panicf("could not insert test client into db: %s", err)
|
||||
}
|
||||
if err := suite.db.Put(context.Background(), suite.testApplication); err != nil {
|
||||
logrus.Panicf("could not insert test application into db: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TearDownTest drops the oauth_clients table and closes the pg connection after each test
|
||||
func (suite *AuthTestSuite) TearDownTest() {
|
||||
models := []interface{}{
|
||||
>smodel.Client{},
|
||||
>smodel.Token{},
|
||||
>smodel.User{},
|
||||
>smodel.Account{},
|
||||
>smodel.Application{},
|
||||
}
|
||||
for _, m := range models {
|
||||
if err := suite.db.DropTable(context.Background(), m); err != nil {
|
||||
logrus.Panicf("error dropping table: %s", err)
|
||||
}
|
||||
}
|
||||
if err := suite.db.Stop(context.Background()); err != nil {
|
||||
logrus.Panicf("error closing db connection: %s", err)
|
||||
}
|
||||
suite.db = nil
|
||||
}
|
||||
|
||||
func TestAuthTestSuite(t *testing.T) {
|
||||
suite.Run(t, new(AuthTestSuite))
|
||||
}
|
||||
// TODO
|
||||
|
@@ -30,6 +30,8 @@ import (
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/oidc"
|
||||
@@ -211,7 +213,8 @@ func (m *Module) parseUserFromClaims(ctx context.Context, claims *oidc.Claims, i
|
||||
password := uuid.NewString() + uuid.NewString()
|
||||
|
||||
// create the user! this will also create an account and store it in the database so we don't need to do that here
|
||||
user, err = m.db.NewSignup(ctx, username, "", m.config.AccountsConfig.RequireApproval, claims.Email, password, ip, "", appID, claims.EmailVerified, admin)
|
||||
requireApproval := viper.GetBool(config.Keys.AccountsApprovalRequired)
|
||||
user, err = m.db.NewSignup(ctx, username, "", requireApproval, claims.Email, password, ip, "", appID, claims.EmailVerified, admin)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating user: %s", err)
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -41,14 +40,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for everything relating to viewing blocks
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new blocks module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -34,14 +33,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for everything related to emoji
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new emoji module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -45,14 +44,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for everything relating to viewing favourites
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new favourites module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
@@ -42,22 +43,20 @@ const (
|
||||
// FileServer implements the RESTAPIModule interface.
|
||||
// The goal here is to serve requested media files if the gotosocial server is configured to use local storage.
|
||||
type FileServer struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
storageBase string
|
||||
processor processing.Processor
|
||||
storageServeBasePath string
|
||||
}
|
||||
|
||||
// New returns a new fileServer module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &FileServer{
|
||||
config: config,
|
||||
processor: processor,
|
||||
storageBase: config.StorageConfig.ServeBasePath,
|
||||
processor: processor,
|
||||
storageServeBasePath: viper.GetString(config.Keys.StorageServeBasePath),
|
||||
}
|
||||
}
|
||||
|
||||
// Route satisfies the RESTAPIModule interface
|
||||
func (m *FileServer) Route(s router.Router) error {
|
||||
s.AttachHandler(http.MethodGet, fmt.Sprintf("%s/:%s/:%s/:%s/:%s", m.storageBase, AccountIDKey, MediaTypeKey, MediaSizeKey, FileNameKey), m.ServeFile)
|
||||
s.AttachHandler(http.MethodGet, fmt.Sprintf("%s/:%s/:%s/:%s/:%s", m.storageServeBasePath, AccountIDKey, MediaTypeKey, MediaSizeKey, FileNameKey), m.ServeFile)
|
||||
return nil
|
||||
}
|
||||
|
@@ -32,7 +32,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/client/fileserver"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
@@ -47,7 +46,6 @@ import (
|
||||
type ServeFileTestSuite struct {
|
||||
// standard suite interfaces
|
||||
suite.Suite
|
||||
config *config.Config
|
||||
db db.DB
|
||||
storage *kv.KVStore
|
||||
federator federation.Federator
|
||||
@@ -75,9 +73,9 @@ type ServeFileTestSuite struct {
|
||||
|
||||
func (suite *ServeFileTestSuite) SetupSuite() {
|
||||
// setup standard items
|
||||
suite.config = testrig.NewTestConfig()
|
||||
suite.db = testrig.NewTestDB()
|
||||
testrig.InitTestConfig()
|
||||
testrig.InitTestLog()
|
||||
suite.db = testrig.NewTestDB()
|
||||
suite.storage = testrig.NewTestStorage()
|
||||
suite.federator = testrig.NewTestFederator(suite.db, testrig.NewTestTransportController(testrig.NewMockHTTPClient(nil), suite.db), suite.storage)
|
||||
suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil)
|
||||
@@ -88,7 +86,7 @@ func (suite *ServeFileTestSuite) SetupSuite() {
|
||||
suite.oauthServer = testrig.NewTestOauthServer(suite.db)
|
||||
|
||||
// setup module being tested
|
||||
suite.fileServer = fileserver.New(suite.config, suite.processor).(*fileserver.FileServer)
|
||||
suite.fileServer = fileserver.New(suite.processor).(*fileserver.FileServer)
|
||||
}
|
||||
|
||||
func (suite *ServeFileTestSuite) TearDownSuite() {
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -34,14 +33,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for every related to filters
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new filter module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -43,14 +42,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new follow request module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ import (
|
||||
|
||||
"codeberg.org/gruf/go-store/kv"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/client/followrequest"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
@@ -39,7 +40,6 @@ import (
|
||||
|
||||
type FollowRequestStandardTestSuite struct {
|
||||
suite.Suite
|
||||
config *config.Config
|
||||
db db.DB
|
||||
storage *kv.KVStore
|
||||
federator federation.Federator
|
||||
@@ -70,14 +70,14 @@ func (suite *FollowRequestStandardTestSuite) SetupSuite() {
|
||||
}
|
||||
|
||||
func (suite *FollowRequestStandardTestSuite) SetupTest() {
|
||||
testrig.InitTestConfig()
|
||||
testrig.InitTestLog()
|
||||
suite.config = testrig.NewTestConfig()
|
||||
suite.db = testrig.NewTestDB()
|
||||
suite.storage = testrig.NewTestStorage()
|
||||
suite.federator = testrig.NewTestFederator(suite.db, testrig.NewTestTransportController(testrig.NewMockHTTPClient(nil), suite.db), suite.storage)
|
||||
suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil)
|
||||
suite.processor = testrig.NewTestProcessor(suite.db, suite.storage, suite.federator, suite.emailSender)
|
||||
suite.followRequestModule = followrequest.New(suite.config, suite.processor).(*followrequest.Module)
|
||||
suite.followRequestModule = followrequest.New(suite.processor).(*followrequest.Module)
|
||||
testrig.StandardDBSetup(suite.db, nil)
|
||||
testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media")
|
||||
}
|
||||
@@ -95,7 +95,10 @@ func (suite *FollowRequestStandardTestSuite) newContext(recorder *httptest.Respo
|
||||
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
|
||||
ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"])
|
||||
|
||||
baseURI := fmt.Sprintf("%s://%s", suite.config.Protocol, suite.config.Host)
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
|
||||
baseURI := fmt.Sprintf("%s://%s", protocol, host)
|
||||
requestURI := fmt.Sprintf("%s/%s", baseURI, requestPath)
|
||||
|
||||
ctx.Request = httptest.NewRequest(requestMethod, requestURI, bytes.NewReader(requestBody)) // the endpoint we're hitting
|
||||
|
@@ -4,7 +4,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -16,14 +15,12 @@ const (
|
||||
|
||||
// Module implements the ClientModule interface
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new instance information module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -1,9 +1,12 @@
|
||||
package instance
|
||||
|
||||
import (
|
||||
"github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -32,7 +35,9 @@ import (
|
||||
func (m *Module) InstanceInformationGETHandler(c *gin.Context) {
|
||||
l := logrus.WithField("func", "InstanceInformationGETHandler")
|
||||
|
||||
instance, err := m.processor.InstanceGet(c.Request.Context(), m.config.Host)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
|
||||
instance, err := m.processor.InstanceGet(c.Request.Context(), host)
|
||||
if err != nil {
|
||||
l.Debugf("error getting instance from processor: %s", err)
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -34,14 +33,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for everything related to lists
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new list module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -38,14 +37,12 @@ const BasePathWithID = BasePath + "/:" + IDKey
|
||||
|
||||
// Module implements the ClientAPIModule interface for media
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new auth module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -21,9 +21,11 @@ package media
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
@@ -102,7 +104,7 @@ func (m *Module) MediaCreatePOSTHandler(c *gin.Context) {
|
||||
|
||||
// Give the fields on the request form a first pass to make sure the request is superficially valid.
|
||||
l.Tracef("validating form %+v", form)
|
||||
if err := validateCreateMedia(form, m.config.MediaConfig); err != nil {
|
||||
if err := validateCreateMedia(form); err != nil {
|
||||
l.Debugf("error validating form: %s", err)
|
||||
c.JSON(http.StatusUnprocessableEntity, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -119,24 +121,30 @@ func (m *Module) MediaCreatePOSTHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, apiAttachment)
|
||||
}
|
||||
|
||||
func validateCreateMedia(form *model.AttachmentRequest, config *config.MediaConfig) error {
|
||||
func validateCreateMedia(form *model.AttachmentRequest) error {
|
||||
// check there actually is a file attached and it's not size 0
|
||||
if form.File == nil {
|
||||
return errors.New("no attachment given")
|
||||
}
|
||||
|
||||
keys := config.Keys
|
||||
maxVideoSize := viper.GetInt(keys.MediaVideoMaxSize)
|
||||
maxImageSize := viper.GetInt(keys.MediaImageMaxSize)
|
||||
minDescriptionChars := viper.GetInt(keys.MediaDescriptionMinChars)
|
||||
maxDescriptionChars := viper.GetInt(keys.MediaDescriptionMaxChars)
|
||||
|
||||
// a very superficial check to see if no size limits are exceeded
|
||||
// we still don't actually know which media types we're dealing with but the other handlers will go into more detail there
|
||||
maxSize := config.MaxVideoSize
|
||||
if config.MaxImageSize > maxSize {
|
||||
maxSize = config.MaxImageSize
|
||||
maxSize := maxVideoSize
|
||||
if maxImageSize > maxSize {
|
||||
maxSize = maxImageSize
|
||||
}
|
||||
if form.File.Size > int64(maxSize) {
|
||||
return fmt.Errorf("file size limit exceeded: limit is %d bytes but attachment was %d bytes", maxSize, form.File.Size)
|
||||
}
|
||||
|
||||
if len(form.Description) < config.MinDescriptionChars || len(form.Description) > config.MaxDescriptionChars {
|
||||
return fmt.Errorf("image description length must be between %d and %d characters (inclusive), but provided image description was %d chars", config.MinDescriptionChars, config.MaxDescriptionChars, len(form.Description))
|
||||
if len(form.Description) < minDescriptionChars || len(form.Description) > maxDescriptionChars {
|
||||
return fmt.Errorf("image description length must be between %d and %d characters (inclusive), but provided image description was %d chars", minDescriptionChars, maxDescriptionChars, len(form.Description))
|
||||
}
|
||||
|
||||
// TODO: validate focus here
|
||||
|
@@ -35,7 +35,6 @@ import (
|
||||
"github.com/stretchr/testify/suite"
|
||||
mediamodule "github.com/superseriousbusiness/gotosocial/internal/api/client/media"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
@@ -50,7 +49,6 @@ import (
|
||||
type MediaCreateTestSuite struct {
|
||||
// standard suite interfaces
|
||||
suite.Suite
|
||||
config *config.Config
|
||||
db db.DB
|
||||
storage *kv.KVStore
|
||||
federator federation.Federator
|
||||
@@ -78,9 +76,9 @@ type MediaCreateTestSuite struct {
|
||||
|
||||
func (suite *MediaCreateTestSuite) SetupSuite() {
|
||||
// setup standard items
|
||||
suite.config = testrig.NewTestConfig()
|
||||
suite.db = testrig.NewTestDB()
|
||||
testrig.InitTestConfig()
|
||||
testrig.InitTestLog()
|
||||
suite.db = testrig.NewTestDB()
|
||||
suite.storage = testrig.NewTestStorage()
|
||||
suite.tc = testrig.NewTestTypeConverter(suite.db)
|
||||
suite.mediaHandler = testrig.NewTestMediaHandler(suite.db, suite.storage)
|
||||
@@ -90,7 +88,7 @@ func (suite *MediaCreateTestSuite) SetupSuite() {
|
||||
suite.processor = testrig.NewTestProcessor(suite.db, suite.storage, suite.federator, suite.emailSender)
|
||||
|
||||
// setup module being tested
|
||||
suite.mediaModule = mediamodule.New(suite.config, suite.processor).(*mediamodule.Module)
|
||||
suite.mediaModule = mediamodule.New(suite.processor).(*mediamodule.Module)
|
||||
}
|
||||
|
||||
func (suite *MediaCreateTestSuite) TearDownSuite() {
|
||||
|
@@ -21,9 +21,11 @@ package media
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
@@ -117,7 +119,7 @@ func (m *Module) MediaPUTHandler(c *gin.Context) {
|
||||
|
||||
// Give the fields on the request form a first pass to make sure the request is superficially valid.
|
||||
l.Tracef("validating form %+v", form)
|
||||
if err := validateUpdateMedia(&form, m.config.MediaConfig); err != nil {
|
||||
if err := validateUpdateMedia(&form); err != nil {
|
||||
l.Debugf("error validating form: %s", err)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -132,11 +134,14 @@ func (m *Module) MediaPUTHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, attachment)
|
||||
}
|
||||
|
||||
func validateUpdateMedia(form *model.AttachmentUpdateRequest, config *config.MediaConfig) error {
|
||||
func validateUpdateMedia(form *model.AttachmentUpdateRequest) error {
|
||||
keys := config.Keys
|
||||
minDescriptionChars := viper.GetInt(keys.MediaDescriptionMinChars)
|
||||
maxDescriptionChars := viper.GetInt(keys.MediaDescriptionMaxChars)
|
||||
|
||||
if form.Description != nil {
|
||||
if len(*form.Description) < config.MinDescriptionChars || len(*form.Description) > config.MaxDescriptionChars {
|
||||
return fmt.Errorf("image description length must be between %d and %d characters (inclusive), but provided image description was %d chars", config.MinDescriptionChars, config.MaxDescriptionChars, len(*form.Description))
|
||||
if len(*form.Description) < minDescriptionChars || len(*form.Description) > maxDescriptionChars {
|
||||
return fmt.Errorf("image description length must be between %d and %d characters (inclusive), but provided image description was %d chars", minDescriptionChars, maxDescriptionChars, len(*form.Description))
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -46,14 +45,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for every related to posting/deleting/interacting with notifications
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new notification module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -65,14 +64,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for everything related to searching
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new search module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -26,7 +26,6 @@ import (
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -75,14 +74,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for every related to posting/deleting/interacting with statuses
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new account module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"codeberg.org/gruf/go-store/kv"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/client/status"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
@@ -35,7 +34,6 @@ import (
|
||||
type StatusStandardTestSuite struct {
|
||||
// standard suite interfaces
|
||||
suite.Suite
|
||||
config *config.Config
|
||||
db db.DB
|
||||
tc typeutils.TypeConverter
|
||||
federator federation.Federator
|
||||
@@ -67,15 +65,15 @@ func (suite *StatusStandardTestSuite) SetupSuite() {
|
||||
}
|
||||
|
||||
func (suite *StatusStandardTestSuite) SetupTest() {
|
||||
suite.config = testrig.NewTestConfig()
|
||||
testrig.InitTestConfig()
|
||||
testrig.InitTestLog()
|
||||
suite.db = testrig.NewTestDB()
|
||||
suite.tc = testrig.NewTestTypeConverter(suite.db)
|
||||
suite.storage = testrig.NewTestStorage()
|
||||
testrig.InitTestLog()
|
||||
suite.federator = testrig.NewTestFederator(suite.db, testrig.NewTestTransportController(testrig.NewMockHTTPClient(nil), suite.db), suite.storage)
|
||||
suite.emailSender = testrig.NewEmailSender("../../../../web/template/", nil)
|
||||
suite.processor = testrig.NewTestProcessor(suite.db, suite.storage, suite.federator, suite.emailSender)
|
||||
suite.statusModule = status.New(suite.config, suite.processor).(*status.Module)
|
||||
suite.statusModule = status.New(suite.processor).(*status.Module)
|
||||
testrig.StandardDBSetup(suite.db, nil)
|
||||
testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media")
|
||||
}
|
||||
|
@@ -21,9 +21,11 @@ package status
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/sirupsen/logrus"
|
||||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
@@ -96,7 +98,7 @@ func (m *Module) StatusCreatePOSTHandler(c *gin.Context) {
|
||||
|
||||
// Give the fields on the request form a first pass to make sure the request is superficially valid.
|
||||
l.Tracef("validating form %+v", form)
|
||||
if err := validateCreateStatus(form, m.config.StatusesConfig); err != nil {
|
||||
if err := validateCreateStatus(form); err != nil {
|
||||
l.Debugf("error validating form: %s", err)
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
||||
return
|
||||
@@ -112,7 +114,7 @@ func (m *Module) StatusCreatePOSTHandler(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, apiStatus)
|
||||
}
|
||||
|
||||
func validateCreateStatus(form *model.AdvancedStatusCreateForm, config *config.StatusesConfig) error {
|
||||
func validateCreateStatus(form *model.AdvancedStatusCreateForm) error {
|
||||
// validate that, structurally, we have a valid status/post
|
||||
if form.Status == "" && form.MediaIDs == nil && form.Poll == nil {
|
||||
return errors.New("no status, media, or poll provided")
|
||||
@@ -122,16 +124,23 @@ func validateCreateStatus(form *model.AdvancedStatusCreateForm, config *config.S
|
||||
return errors.New("can't post media + poll in same status")
|
||||
}
|
||||
|
||||
keys := config.Keys
|
||||
maxChars := viper.GetInt(keys.StatusesMaxChars)
|
||||
maxMediaFiles := viper.GetInt(keys.StatusesMediaMaxFiles)
|
||||
maxPollOptions := viper.GetInt(keys.StatusesPollMaxOptions)
|
||||
maxPollChars := viper.GetInt(keys.StatusesPollOptionMaxChars)
|
||||
maxCwChars := viper.GetInt(keys.StatusesCWMaxChars)
|
||||
|
||||
// validate status
|
||||
if form.Status != "" {
|
||||
if len(form.Status) > config.MaxChars {
|
||||
return fmt.Errorf("status too long, %d characters provided but limit is %d", len(form.Status), config.MaxChars)
|
||||
if len(form.Status) > maxChars {
|
||||
return fmt.Errorf("status too long, %d characters provided but limit is %d", len(form.Status), maxChars)
|
||||
}
|
||||
}
|
||||
|
||||
// validate media attachments
|
||||
if len(form.MediaIDs) > config.MaxMediaFiles {
|
||||
return fmt.Errorf("too many media files attached to status, %d attached but limit is %d", len(form.MediaIDs), config.MaxMediaFiles)
|
||||
if len(form.MediaIDs) > maxMediaFiles {
|
||||
return fmt.Errorf("too many media files attached to status, %d attached but limit is %d", len(form.MediaIDs), maxMediaFiles)
|
||||
}
|
||||
|
||||
// validate poll
|
||||
@@ -139,20 +148,20 @@ func validateCreateStatus(form *model.AdvancedStatusCreateForm, config *config.S
|
||||
if form.Poll.Options == nil {
|
||||
return errors.New("poll with no options")
|
||||
}
|
||||
if len(form.Poll.Options) > config.PollMaxOptions {
|
||||
return fmt.Errorf("too many poll options provided, %d provided but limit is %d", len(form.Poll.Options), config.PollMaxOptions)
|
||||
if len(form.Poll.Options) > maxPollOptions {
|
||||
return fmt.Errorf("too many poll options provided, %d provided but limit is %d", len(form.Poll.Options), maxPollOptions)
|
||||
}
|
||||
for _, p := range form.Poll.Options {
|
||||
if len(p) > config.PollOptionMaxChars {
|
||||
return fmt.Errorf("poll option too long, %d characters provided but limit is %d", len(p), config.PollOptionMaxChars)
|
||||
if len(p) > maxPollChars {
|
||||
return fmt.Errorf("poll option too long, %d characters provided but limit is %d", len(p), maxPollChars)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// validate spoiler text/cw
|
||||
if form.SpoilerText != "" {
|
||||
if len(form.SpoilerText) > config.CWMaxChars {
|
||||
return fmt.Errorf("content-warning/spoilertext too long, %d characters provided but limit is %d", len(form.SpoilerText), config.CWMaxChars)
|
||||
if len(form.SpoilerText) > maxCwChars {
|
||||
return fmt.Errorf("content-warning/spoilertext too long, %d characters provided but limit is %d", len(form.SpoilerText), maxCwChars)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -40,14 +39,12 @@ const (
|
||||
|
||||
// Module implements the api.ClientModule interface for everything related to streaming
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new streaming module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -48,14 +47,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface for everything relating to viewing timelines
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new timeline module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/processing"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
)
|
||||
@@ -36,14 +35,12 @@ const (
|
||||
|
||||
// Module implements the ClientAPIModule interface
|
||||
type Module struct {
|
||||
config *config.Config
|
||||
processor processing.Processor
|
||||
}
|
||||
|
||||
// New returns a new user module
|
||||
func New(config *config.Config, processor processing.Processor) api.ClientModule {
|
||||
func New(processor processing.Processor) api.ClientModule {
|
||||
return &Module{
|
||||
config: config,
|
||||
processor: processor,
|
||||
}
|
||||
}
|
||||
|
@@ -22,7 +22,6 @@ import (
|
||||
"codeberg.org/gruf/go-store/kv"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/client/user"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/federation"
|
||||
@@ -34,7 +33,6 @@ import (
|
||||
|
||||
type UserStandardTestSuite struct {
|
||||
suite.Suite
|
||||
config *config.Config
|
||||
db db.DB
|
||||
tc typeutils.TypeConverter
|
||||
federator federation.Federator
|
||||
@@ -54,21 +52,21 @@ type UserStandardTestSuite struct {
|
||||
}
|
||||
|
||||
func (suite *UserStandardTestSuite) SetupTest() {
|
||||
testrig.InitTestLog()
|
||||
testrig.InitTestConfig()
|
||||
suite.testTokens = testrig.NewTestTokens()
|
||||
suite.testClients = testrig.NewTestClients()
|
||||
suite.testApplications = testrig.NewTestApplications()
|
||||
suite.testUsers = testrig.NewTestUsers()
|
||||
suite.testAccounts = testrig.NewTestAccounts()
|
||||
suite.config = testrig.NewTestConfig()
|
||||
suite.db = testrig.NewTestDB()
|
||||
suite.storage = testrig.NewTestStorage()
|
||||
testrig.InitTestLog()
|
||||
suite.tc = testrig.NewTestTypeConverter(suite.db)
|
||||
suite.federator = testrig.NewTestFederator(suite.db, testrig.NewTestTransportController(testrig.NewMockHTTPClient(nil), suite.db), suite.storage)
|
||||
suite.sentEmails = make(map[string]string)
|
||||
suite.emailSender = testrig.NewEmailSender("../../../../web/template/", suite.sentEmails)
|
||||
suite.processor = testrig.NewTestProcessor(suite.db, suite.storage, suite.federator, suite.emailSender)
|
||||
suite.userModule = user.New(suite.config, suite.processor).(*user.Module)
|
||||
suite.userModule = user.New(suite.processor).(*user.Module)
|
||||
testrig.StandardDBSetup(suite.db, suite.testAccounts)
|
||||
testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media")
|
||||
}
|
||||
|
Reference in New Issue
Block a user