summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2021-12-07 13:31:39 +0100
committerLibravatar GitHub <noreply@github.com>2021-12-07 13:31:39 +0100
commit0884f89431cd26bcc9674b3b7ab628b090f5881e (patch)
treecdd3b3f77f780a8b59d075dbcc3d4d013811e405 /internal
parentUpdate dependencies (#333) (diff)
downloadgotosocial-0884f89431cd26bcc9674b3b7ab628b090f5881e.tar.xz
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
Diffstat (limited to 'internal')
-rw-r--r--internal/api/client/account/account.go5
-rw-r--r--internal/api/client/account/account_test.go11
-rw-r--r--internal/api/client/account/accountcreate.go14
-rw-r--r--internal/api/client/admin/admin.go5
-rw-r--r--internal/api/client/app/app.go5
-rw-r--r--internal/api/client/auth/auth.go5
-rw-r--r--internal/api/client/auth/auth_test.go132
-rw-r--r--internal/api/client/auth/callback.go5
-rw-r--r--internal/api/client/blocks/blocks.go5
-rw-r--r--internal/api/client/emoji/emoji.go5
-rw-r--r--internal/api/client/favourites/favourites.go5
-rw-r--r--internal/api/client/fileserver/fileserver.go15
-rw-r--r--internal/api/client/fileserver/servefile_test.go8
-rw-r--r--internal/api/client/filter/filter.go5
-rw-r--r--internal/api/client/followrequest/followrequest.go5
-rw-r--r--internal/api/client/followrequest/followrequest_test.go11
-rw-r--r--internal/api/client/instance/instance.go5
-rw-r--r--internal/api/client/instance/instanceget.go9
-rw-r--r--internal/api/client/list/list.go5
-rw-r--r--internal/api/client/media/media.go5
-rw-r--r--internal/api/client/media/mediacreate.go24
-rw-r--r--internal/api/client/media/mediacreate_test.go8
-rw-r--r--internal/api/client/media/mediaupdate.go15
-rw-r--r--internal/api/client/notification/notification.go5
-rw-r--r--internal/api/client/search/search.go5
-rw-r--r--internal/api/client/status/status.go5
-rw-r--r--internal/api/client/status/status_test.go8
-rw-r--r--internal/api/client/status/statuscreate.go35
-rw-r--r--internal/api/client/streaming/streaming.go5
-rw-r--r--internal/api/client/timeline/timeline.go5
-rw-r--r--internal/api/client/user/user.go5
-rw-r--r--internal/api/client/user/user_test.go8
-rw-r--r--internal/api/s2s/nodeinfo/nodeinfo.go5
-rw-r--r--internal/api/s2s/user/inboxpost_test.go8
-rw-r--r--internal/api/s2s/user/outboxget_test.go6
-rw-r--r--internal/api/s2s/user/repliesget_test.go6
-rw-r--r--internal/api/s2s/user/user.go5
-rw-r--r--internal/api/s2s/user/user_test.go11
-rw-r--r--internal/api/s2s/user/userget_test.go2
-rw-r--r--internal/api/s2s/webfinger/webfinger.go5
-rw-r--r--internal/api/s2s/webfinger/webfinger_test.go11
-rw-r--r--internal/api/s2s/webfinger/webfingerget.go15
-rw-r--r--internal/api/s2s/webfinger/webfingerget_test.go30
-rw-r--r--internal/api/security/security.go5
-rw-r--r--internal/cliactions/action.go30
-rw-r--r--internal/cliactions/admin/account/account.go257
-rw-r--r--internal/cliactions/admin/trans/export.go51
-rw-r--r--internal/cliactions/admin/trans/import.go51
-rw-r--r--internal/cliactions/server/server.go204
-rw-r--r--internal/cliactions/testrig/testrig.go167
-rw-r--r--internal/config/accounts.go29
-rw-r--r--internal/config/config.go622
-rw-r--r--internal/config/db.go49
-rw-r--r--internal/config/default.go289
-rw-r--r--internal/config/defaults.go87
-rw-r--r--internal/config/file.go (renamed from internal/config/template.go)23
-rw-r--r--internal/config/keys.go175
-rw-r--r--internal/config/letsencrypt.go13
-rw-r--r--internal/config/media.go31
-rw-r--r--internal/config/oidc.go30
-rw-r--r--internal/config/statuses.go33
-rw-r--r--internal/config/storage.go36
-rw-r--r--internal/config/values.go90
-rw-r--r--internal/config/viper.go (renamed from internal/config/smtp.go)33
-rw-r--r--internal/db/bundb/account.go9
-rw-r--r--internal/db/bundb/admin.go25
-rw-r--r--internal/db/bundb/basic.go4
-rw-r--r--internal/db/bundb/bundb.go149
-rw-r--r--internal/db/bundb/bundb_test.go8
-rw-r--r--internal/db/bundb/domain.go4
-rw-r--r--internal/db/bundb/instance.go14
-rw-r--r--internal/db/bundb/media.go4
-rw-r--r--internal/db/bundb/mention.go6
-rw-r--r--internal/db/bundb/notification.go6
-rw-r--r--internal/db/bundb/relationship.go4
-rw-r--r--internal/db/bundb/session.go4
-rw-r--r--internal/db/bundb/status.go6
-rw-r--r--internal/db/bundb/timeline.go4
-rw-r--r--internal/email/noopsender.go6
-rw-r--r--internal/email/sender.go20
-rw-r--r--internal/federation/authenticate.go5
-rw-r--r--internal/federation/dereferencing/dereferencer.go5
-rw-r--r--internal/federation/dereferencing/dereferencer_test.go9
-rw-r--r--internal/federation/dereferencing/thread.go14
-rw-r--r--internal/federation/federatingdb/db.go7
-rw-r--r--internal/federation/federatingdb/federatingdb_test.go6
-rw-r--r--internal/federation/federatingdb/owns.go7
-rw-r--r--internal/federation/federatingdb/reject_test.go2
-rw-r--r--internal/federation/federatingdb/update.go5
-rw-r--r--internal/federation/federatingdb/util.go9
-rw-r--r--internal/federation/federator.go7
-rw-r--r--internal/federation/federator_test.go14
-rw-r--r--internal/gotosocial/gotosocial.go5
-rw-r--r--internal/media/handler.go18
-rw-r--r--internal/media/processicon.go9
-rw-r--r--internal/media/processimage.go9
-rw-r--r--internal/oauth/clientstore_test.go2
-rw-r--r--internal/oidc/idp.go47
-rw-r--r--internal/processing/account/account.go7
-rw-r--r--internal/processing/account/account_test.go9
-rw-r--r--internal/processing/account/create.go10
-rw-r--r--internal/processing/account/createblock.go2
-rw-r--r--internal/processing/account/createfollow.go2
-rw-r--r--internal/processing/account/update.go15
-rw-r--r--internal/processing/admin/admin.go5
-rw-r--r--internal/processing/blocks.go13
-rw-r--r--internal/processing/federation/federation.go5
-rw-r--r--internal/processing/federation/getnodeinfo.go14
-rw-r--r--internal/processing/federation/getwebfinger.go6
-rw-r--r--internal/processing/instance.go13
-rw-r--r--internal/processing/media/media.go5
-rw-r--r--internal/processing/processor.go16
-rw-r--r--internal/processing/processor_test.go9
-rw-r--r--internal/processing/search.go5
-rw-r--r--internal/processing/status/create.go2
-rw-r--r--internal/processing/status/fave.go2
-rw-r--r--internal/processing/status/status.go7
-rw-r--r--internal/processing/status/status_test.go32
-rw-r--r--internal/processing/status/util_test.go30
-rw-r--r--internal/processing/streaming/streaming_test.go4
-rw-r--r--internal/processing/timeline.go16
-rw-r--r--internal/processing/user/emailconfirm.go7
-rw-r--r--internal/processing/user/user.go5
-rw-r--r--internal/processing/user/user_test.go7
-rw-r--r--internal/router/cors.go3
-rw-r--r--internal/router/router.go42
-rw-r--r--internal/router/session.go20
-rw-r--r--internal/router/session_test.go48
-rw-r--r--internal/router/template.go6
-rw-r--r--internal/text/formatter.go9
-rw-r--r--internal/text/formatter_test.go10
-rw-r--r--internal/timeline/get_test.go5
-rw-r--r--internal/timeline/index_test.go5
-rw-r--r--internal/timeline/manager.go5
-rw-r--r--internal/timeline/manager_test.go5
-rw-r--r--internal/timeline/timeline_test.go6
-rw-r--r--internal/trans/trans_test.go3
-rw-r--r--internal/transport/controller.go13
-rw-r--r--internal/typeutils/converter.go5
-rw-r--r--internal/typeutils/converter_test.go9
-rw-r--r--internal/typeutils/internal.go2
-rw-r--r--internal/typeutils/internaltoas.go5
-rw-r--r--internal/typeutils/internaltofrontend.go35
-rw-r--r--internal/typeutils/wrap.go2
-rw-r--r--internal/util/uri.go27
-rw-r--r--internal/visibility/filter_test.go6
-rw-r--r--internal/web/base.go17
-rw-r--r--internal/web/confirmemail.go5
-rw-r--r--internal/web/thread.go8
149 files changed, 1119 insertions, 2685 deletions
diff --git a/internal/api/client/account/account.go b/internal/api/client/account/account.go
index 6e8b1e242..d75fb8e9c 100644
--- a/internal/api/client/account/account.go
+++ b/internal/api/client/account/account.go
@@ -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,
}
}
diff --git a/internal/api/client/account/account_test.go b/internal/api/client/account/account_test.go
index 315ddfce3..f7dfa4520 100644
--- a/internal/api/client/account/account_test.go
+++ b/internal/api/client/account/account_test.go
@@ -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
diff --git a/internal/api/client/account/accountcreate.go b/internal/api/client/account/accountcreate.go
index 6497d4d01..ae9d7b0d7 100644
--- a/internal/api/client/account/accountcreate.go
+++ b/internal/api/client/account/accountcreate.go
@@ -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
}
diff --git a/internal/api/client/admin/admin.go b/internal/api/client/admin/admin.go
index 35d162139..f611807a6 100644
--- a/internal/api/client/admin/admin.go
+++ b/internal/api/client/admin/admin.go
@@ -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,
}
}
diff --git a/internal/api/client/app/app.go b/internal/api/client/app/app.go
index b3df7c388..a5f4c9bcd 100644
--- a/internal/api/client/app/app.go
+++ b/internal/api/client/app/app.go
@@ -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,
}
}
diff --git a/internal/api/client/auth/auth.go b/internal/api/client/auth/auth.go
index 7d9a0caf5..2552331a6 100644
--- a/internal/api/client/auth/auth.go
+++ b/internal/api/client/auth/auth.go
@@ -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,
diff --git a/internal/api/client/auth/auth_test.go b/internal/api/client/auth/auth_test.go
index ae58ffbbb..7f2a78ada 100644
--- a/internal/api/client/auth/auth_test.go
+++ b/internal/api/client/auth/auth_test.go
@@ -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 = &gtsmodel.Account{
- ID: acctID,
- Username: "test_user",
- }
- suite.testUser = &gtsmodel.User{
- EncryptedPassword: string(encryptedPassword),
- Email: "user@example.org",
- AccountID: acctID,
- }
- suite.testClient = &gtsmodel.Client{
- ID: "a-known-client-id",
- Secret: "some-secret",
- Domain: fmt.Sprintf("%s://%s", c.Protocol, c.Host),
- }
- suite.testApplication = &gtsmodel.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{}{
- &gtsmodel.Client{},
- &gtsmodel.Token{},
- &gtsmodel.User{},
- &gtsmodel.Account{},
- &gtsmodel.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
diff --git a/internal/api/client/auth/callback.go b/internal/api/client/auth/callback.go
index 286bcd935..d50fea3db 100644
--- a/internal/api/client/auth/callback.go
+++ b/internal/api/client/auth/callback.go
@@ -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)
}
diff --git a/internal/api/client/blocks/blocks.go b/internal/api/client/blocks/blocks.go
index 531dfa8d8..552a6c599 100644
--- a/internal/api/client/blocks/blocks.go
+++ b/internal/api/client/blocks/blocks.go
@@ -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,
}
}
diff --git a/internal/api/client/emoji/emoji.go b/internal/api/client/emoji/emoji.go
index 4c69fbcc2..4ce021d8f 100644
--- a/internal/api/client/emoji/emoji.go
+++ b/internal/api/client/emoji/emoji.go
@@ -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,
}
}
diff --git a/internal/api/client/favourites/favourites.go b/internal/api/client/favourites/favourites.go
index daaab82f8..f03372ccd 100644
--- a/internal/api/client/favourites/favourites.go
+++ b/internal/api/client/favourites/favourites.go
@@ -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,
}
}
diff --git a/internal/api/client/fileserver/fileserver.go b/internal/api/client/fileserver/fileserver.go
index e60105686..092a15256 100644
--- a/internal/api/client/fileserver/fileserver.go
+++ b/internal/api/client/fileserver/fileserver.go
@@ -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
}
diff --git a/internal/api/client/fileserver/servefile_test.go b/internal/api/client/fileserver/servefile_test.go
index 692122a7b..b93f97606 100644
--- a/internal/api/client/fileserver/servefile_test.go
+++ b/internal/api/client/fileserver/servefile_test.go
@@ -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() {
diff --git a/internal/api/client/filter/filter.go b/internal/api/client/filter/filter.go
index 2ec53bd0a..e8dea8170 100644
--- a/internal/api/client/filter/filter.go
+++ b/internal/api/client/filter/filter.go
@@ -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,
}
}
diff --git a/internal/api/client/followrequest/followrequest.go b/internal/api/client/followrequest/followrequest.go
index 4f46e1654..75fbbea10 100644
--- a/internal/api/client/followrequest/followrequest.go
+++ b/internal/api/client/followrequest/followrequest.go
@@ -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,
}
}
diff --git a/internal/api/client/followrequest/followrequest_test.go b/internal/api/client/followrequest/followrequest_test.go
index 3c2cc32d0..e7dccc210 100644
--- a/internal/api/client/followrequest/followrequest_test.go
+++ b/internal/api/client/followrequest/followrequest_test.go
@@ -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
diff --git a/internal/api/client/instance/instance.go b/internal/api/client/instance/instance.go
index 33e0054c3..758cce376 100644
--- a/internal/api/client/instance/instance.go
+++ b/internal/api/client/instance/instance.go
@@ -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,
}
}
diff --git a/internal/api/client/instance/instanceget.go b/internal/api/client/instance/instanceget.go
index fac917b25..f2f496cb5 100644
--- a/internal/api/client/instance/instanceget.go
+++ b/internal/api/client/instance/instanceget.go
@@ -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"})
diff --git a/internal/api/client/list/list.go b/internal/api/client/list/list.go
index 106682ca9..347525d54 100644
--- a/internal/api/client/list/list.go
+++ b/internal/api/client/list/list.go
@@ -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,
}
}
diff --git a/internal/api/client/media/media.go b/internal/api/client/media/media.go
index a051dea48..669ce9ce9 100644
--- a/internal/api/client/media/media.go
+++ b/internal/api/client/media/media.go
@@ -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,
}
}
diff --git a/internal/api/client/media/mediacreate.go b/internal/api/client/media/mediacreate.go
index 5b7a2dea7..f808b554c 100644
--- a/internal/api/client/media/mediacreate.go
+++ b/internal/api/client/media/mediacreate.go
@@ -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
diff --git a/internal/api/client/media/mediacreate_test.go b/internal/api/client/media/mediacreate_test.go
index 9ad1b9001..f8a17c9de 100644
--- a/internal/api/client/media/mediacreate_test.go
+++ b/internal/api/client/media/mediacreate_test.go
@@ -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() {
diff --git a/internal/api/client/media/mediaupdate.go b/internal/api/client/media/mediaupdate.go
index 2a6d056bb..c22e4e919 100644
--- a/internal/api/client/media/mediaupdate.go
+++ b/internal/api/client/media/mediaupdate.go
@@ -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))
}
}
diff --git a/internal/api/client/notification/notification.go b/internal/api/client/notification/notification.go
index 04a1c2909..bc2d1e4bb 100644
--- a/internal/api/client/notification/notification.go
+++ b/internal/api/client/notification/notification.go
@@ -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,
}
}
diff --git a/internal/api/client/search/search.go b/internal/api/client/search/search.go
index 474cccb27..b0b9c8613 100644
--- a/internal/api/client/search/search.go
+++ b/internal/api/client/search/search.go
@@ -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,
}
}
diff --git a/internal/api/client/status/status.go b/internal/api/client/status/status.go
index 6c7f077e1..2c6fc614a 100644
--- a/internal/api/client/status/status.go
+++ b/internal/api/client/status/status.go
@@ -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,
}
}
diff --git a/internal/api/client/status/status_test.go b/internal/api/client/status/status_test.go
index 399873fcc..0af5b78c2 100644
--- a/internal/api/client/status/status_test.go
+++ b/internal/api/client/status/status_test.go
@@ -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")
}
diff --git a/internal/api/client/status/statuscreate.go b/internal/api/client/status/statuscreate.go
index e9d92890e..629a325c5 100644
--- a/internal/api/client/status/statuscreate.go
+++ b/internal/api/client/status/statuscreate.go
@@ -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)
}
}
diff --git a/internal/api/client/streaming/streaming.go b/internal/api/client/streaming/streaming.go
index fd52419e0..cd499455f 100644
--- a/internal/api/client/streaming/streaming.go
+++ b/internal/api/client/streaming/streaming.go
@@ -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,
}
}
diff --git a/internal/api/client/timeline/timeline.go b/internal/api/client/timeline/timeline.go
index 2aa939f61..3e9b37e07 100644
--- a/internal/api/client/timeline/timeline.go
+++ b/internal/api/client/timeline/timeline.go
@@ -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,
}
}
diff --git a/internal/api/client/user/user.go b/internal/api/client/user/user.go
index ff28a197f..89f71344b 100644
--- a/internal/api/client/user/user.go
+++ b/internal/api/client/user/user.go
@@ -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,
}
}
diff --git a/internal/api/client/user/user_test.go b/internal/api/client/user/user_test.go
index 76d95b2d9..4a9a1a9d7 100644
--- a/internal/api/client/user/user_test.go
+++ b/internal/api/client/user/user_test.go
@@ -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")
}
diff --git a/internal/api/s2s/nodeinfo/nodeinfo.go b/internal/api/s2s/nodeinfo/nodeinfo.go
index 5d1d03b24..1cbf32760 100644
--- a/internal/api/s2s/nodeinfo/nodeinfo.go
+++ b/internal/api/s2s/nodeinfo/nodeinfo.go
@@ -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 FederationModule interface
type Module struct {
- config *config.Config
processor processing.Processor
}
// New returns a new nodeinfo module
-func New(config *config.Config, processor processing.Processor) api.FederationModule {
+func New(processor processing.Processor) api.FederationModule {
return &Module{
- config: config,
processor: processor,
}
}
diff --git a/internal/api/s2s/user/inboxpost_test.go b/internal/api/s2s/user/inboxpost_test.go
index 4d1c05757..716dcfc25 100644
--- a/internal/api/s2s/user/inboxpost_test.go
+++ b/internal/api/s2s/user/inboxpost_test.go
@@ -87,7 +87,7 @@ func (suite *InboxPostTestSuite) TestPostBlock() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
@@ -187,7 +187,7 @@ func (suite *InboxPostTestSuite) TestPostUnblock() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
@@ -277,7 +277,7 @@ func (suite *InboxPostTestSuite) TestPostUpdate() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
@@ -398,7 +398,7 @@ func (suite *InboxPostTestSuite) TestPostDelete() {
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
err = processor.Start(context.Background())
suite.NoError(err)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
diff --git a/internal/api/s2s/user/outboxget_test.go b/internal/api/s2s/user/outboxget_test.go
index 251051cbd..4cd556bbe 100644
--- a/internal/api/s2s/user/outboxget_test.go
+++ b/internal/api/s2s/user/outboxget_test.go
@@ -48,7 +48,7 @@ func (suite *OutboxGetTestSuite) TestGetOutbox() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
@@ -102,7 +102,7 @@ func (suite *OutboxGetTestSuite) TestGetOutboxFirstPage() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
@@ -156,7 +156,7 @@ func (suite *OutboxGetTestSuite) TestGetOutboxNextPage() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
diff --git a/internal/api/s2s/user/repliesget_test.go b/internal/api/s2s/user/repliesget_test.go
index cd1094b53..a4229bb21 100644
--- a/internal/api/s2s/user/repliesget_test.go
+++ b/internal/api/s2s/user/repliesget_test.go
@@ -51,7 +51,7 @@ func (suite *RepliesGetTestSuite) TestGetReplies() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
@@ -111,7 +111,7 @@ func (suite *RepliesGetTestSuite) TestGetRepliesNext() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
@@ -174,7 +174,7 @@ func (suite *RepliesGetTestSuite) TestGetRepliesLast() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
diff --git a/internal/api/s2s/user/user.go b/internal/api/s2s/user/user.go
index 56b940f1d..891f2c1b1 100644
--- a/internal/api/s2s/user/user.go
+++ b/internal/api/s2s/user/user.go
@@ -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"
"github.com/superseriousbusiness/gotosocial/internal/util"
@@ -66,14 +65,12 @@ const (
// Module implements the FederationAPIModule interface
type Module struct {
- config *config.Config
processor processing.Processor
}
// New returns a new auth module
-func New(config *config.Config, processor processing.Processor) api.FederationModule {
+func New(processor processing.Processor) api.FederationModule {
return &Module{
- config: config,
processor: processor,
}
}
diff --git a/internal/api/s2s/user/user_test.go b/internal/api/s2s/user/user_test.go
index da305488f..ed6a83312 100644
--- a/internal/api/s2s/user/user_test.go
+++ b/internal/api/s2s/user/user_test.go
@@ -23,7 +23,6 @@ import (
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/api/s2s/user"
"github.com/superseriousbusiness/gotosocial/internal/api/security"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/email"
"github.com/superseriousbusiness/gotosocial/internal/federation"
@@ -37,7 +36,6 @@ import (
type UserStandardTestSuite struct {
// standard suite interfaces
suite.Suite
- config *config.Config
db db.DB
tc typeutils.TypeConverter
federator federation.Federator
@@ -73,17 +71,18 @@ func (suite *UserStandardTestSuite) SetupSuite() {
}
func (suite *UserStandardTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
+ testrig.InitTestLog()
+ testrig.InitTestConfig()
+
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.userModule = user.New(suite.config, suite.processor).(*user.Module)
+ suite.userModule = user.New(suite.processor).(*user.Module)
suite.oauthServer = testrig.NewTestOauthServer(suite.db)
- suite.securityModule = security.New(suite.config, suite.db, suite.oauthServer).(*security.Module)
+ suite.securityModule = security.New(suite.db, suite.oauthServer).(*security.Module)
testrig.StandardDBSetup(suite.db, suite.testAccounts)
testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media")
}
diff --git a/internal/api/s2s/user/userget_test.go b/internal/api/s2s/user/userget_test.go
index 303295cfe..8ad4a8151 100644
--- a/internal/api/s2s/user/userget_test.go
+++ b/internal/api/s2s/user/userget_test.go
@@ -49,7 +49,7 @@ func (suite *UserGetTestSuite) TestGetUser() {
federator := testrig.NewTestFederator(suite.db, tc, suite.storage)
emailSender := testrig.NewEmailSender("../../../../web/template/", nil)
processor := testrig.NewTestProcessor(suite.db, suite.storage, federator, emailSender)
- userModule := user.New(suite.config, processor).(*user.Module)
+ userModule := user.New(processor).(*user.Module)
// setup request
recorder := httptest.NewRecorder()
diff --git a/internal/api/s2s/webfinger/webfinger.go b/internal/api/s2s/webfinger/webfinger.go
index c447d730e..2ad77d56f 100644
--- a/internal/api/s2s/webfinger/webfinger.go
+++ b/internal/api/s2s/webfinger/webfinger.go
@@ -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 FederationModule interface
type Module struct {
- config *config.Config
processor processing.Processor
}
// New returns a new webfinger module
-func New(config *config.Config, processor processing.Processor) api.FederationModule {
+func New(processor processing.Processor) api.FederationModule {
return &Module{
- config: config,
processor: processor,
}
}
diff --git a/internal/api/s2s/webfinger/webfinger_test.go b/internal/api/s2s/webfinger/webfinger_test.go
index 679dbcd5d..f2e6d0659 100644
--- a/internal/api/s2s/webfinger/webfinger_test.go
+++ b/internal/api/s2s/webfinger/webfinger_test.go
@@ -28,7 +28,6 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger"
"github.com/superseriousbusiness/gotosocial/internal/api/security"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/email"
"github.com/superseriousbusiness/gotosocial/internal/federation"
@@ -42,7 +41,6 @@ import (
type WebfingerStandardTestSuite struct {
// standard suite interfaces
suite.Suite
- config *config.Config
db db.DB
tc typeutils.TypeConverter
federator federation.Federator
@@ -76,17 +74,18 @@ func (suite *WebfingerStandardTestSuite) SetupSuite() {
}
func (suite *WebfingerStandardTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
+ testrig.InitTestLog()
+ testrig.InitTestConfig()
+
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.webfingerModule = webfinger.New(suite.config, suite.processor).(*webfinger.Module)
+ suite.webfingerModule = webfinger.New(suite.processor).(*webfinger.Module)
suite.oauthServer = testrig.NewTestOauthServer(suite.db)
- suite.securityModule = security.New(suite.config, suite.db, suite.oauthServer).(*security.Module)
+ suite.securityModule = security.New(suite.db, suite.oauthServer).(*security.Module)
testrig.StandardDBSetup(suite.db, suite.testAccounts)
testrig.StandardStorageSetup(suite.storage, "../../../../testrig/media")
}
diff --git a/internal/api/s2s/webfinger/webfingerget.go b/internal/api/s2s/webfinger/webfingerget.go
index 3552394f2..b7f3c714d 100644
--- a/internal/api/s2s/webfinger/webfingerget.go
+++ b/internal/api/s2s/webfinger/webfingerget.go
@@ -26,6 +26,8 @@ import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/util"
)
@@ -59,16 +61,19 @@ func (m *Module) WebfingerGETRequest(c *gin.Context) {
}
username := strings.ToLower(usernameAndAccountDomain[0])
- accountDomain := strings.ToLower(usernameAndAccountDomain[1])
- if username == "" || accountDomain == "" {
+ requestedAccountDomain := strings.ToLower(usernameAndAccountDomain[1])
+ if username == "" || requestedAccountDomain == "" {
l.Debug("aborting request because username or domain was empty")
c.JSON(http.StatusBadRequest, gin.H{"error": "bad request"})
return
}
- if accountDomain != m.config.AccountDomain && accountDomain != m.config.Host {
- l.Debugf("aborting request because accountDomain %s does not belong to this instance", accountDomain)
- c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("accountDomain %s does not belong to this instance", accountDomain)})
+ accountDomain := viper.GetString(config.Keys.AccountDomain)
+ host := viper.GetString(config.Keys.Host)
+
+ if requestedAccountDomain != accountDomain && requestedAccountDomain != host {
+ l.Debugf("aborting request because accountDomain %s does not belong to this instance", requestedAccountDomain)
+ c.JSON(http.StatusBadRequest, gin.H{"error": fmt.Sprintf("accountDomain %s does not belong to this instance", requestedAccountDomain)})
return
}
diff --git a/internal/api/s2s/webfinger/webfingerget_test.go b/internal/api/s2s/webfinger/webfingerget_test.go
index 19c637929..8314972d6 100644
--- a/internal/api/s2s/webfinger/webfingerget_test.go
+++ b/internal/api/s2s/webfinger/webfingerget_test.go
@@ -27,9 +27,11 @@ import (
"testing"
"github.com/gin-gonic/gin"
+ "github.com/spf13/viper"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/processing"
"github.com/superseriousbusiness/gotosocial/testrig"
)
@@ -42,7 +44,8 @@ func (suite *WebfingerGetTestSuite) TestFingerUser() {
targetAccount := suite.testAccounts["local_account_1"]
// setup request
- requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, suite.config.Host)
+ host := viper.GetString(config.Keys.Host)
+ requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, host)
recorder := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(recorder)
@@ -63,10 +66,10 @@ func (suite *WebfingerGetTestSuite) TestFingerUser() {
}
func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByHost() {
- suite.config.Host = "gts.example.org"
- suite.config.AccountDomain = "example.org"
- suite.processor = processing.NewProcessor(suite.config, suite.tc, suite.federator, testrig.NewTestOauthServer(suite.db), testrig.NewTestMediaHandler(suite.db, suite.storage), suite.storage, testrig.NewTestTimelineManager(suite.db), suite.db, suite.emailSender)
- suite.webfingerModule = webfinger.New(suite.config, suite.processor).(*webfinger.Module)
+ viper.Set(config.Keys.Host, "gts.example.org")
+ viper.Set(config.Keys.AccountDomain, "example.org")
+ suite.processor = processing.NewProcessor(suite.tc, suite.federator, testrig.NewTestOauthServer(suite.db), testrig.NewTestMediaHandler(suite.db, suite.storage), suite.storage, testrig.NewTestTimelineManager(suite.db), suite.db, suite.emailSender)
+ suite.webfingerModule = webfinger.New(suite.processor).(*webfinger.Module)
targetAccount := accountDomainAccount()
if err := suite.db.Put(context.Background(), targetAccount); err != nil {
@@ -74,7 +77,8 @@ func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByHo
}
// setup request
- requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, suite.config.Host)
+ host := viper.GetString(config.Keys.Host)
+ requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, host)
recorder := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(recorder)
@@ -95,10 +99,10 @@ func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByHo
}
func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByAccountDomain() {
- suite.config.Host = "gts.example.org"
- suite.config.AccountDomain = "example.org"
- suite.processor = processing.NewProcessor(suite.config, suite.tc, suite.federator, testrig.NewTestOauthServer(suite.db), testrig.NewTestMediaHandler(suite.db, suite.storage), suite.storage, testrig.NewTestTimelineManager(suite.db), suite.db, suite.emailSender)
- suite.webfingerModule = webfinger.New(suite.config, suite.processor).(*webfinger.Module)
+ viper.Set(config.Keys.Host, "gts.example.org")
+ viper.Set(config.Keys.AccountDomain, "example.org")
+ suite.processor = processing.NewProcessor(suite.tc, suite.federator, testrig.NewTestOauthServer(suite.db), testrig.NewTestMediaHandler(suite.db, suite.storage), suite.storage, testrig.NewTestTimelineManager(suite.db), suite.db, suite.emailSender)
+ suite.webfingerModule = webfinger.New(suite.processor).(*webfinger.Module)
targetAccount := accountDomainAccount()
if err := suite.db.Put(context.Background(), targetAccount); err != nil {
@@ -106,7 +110,8 @@ func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByAc
}
// setup request
- requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, suite.config.AccountDomain)
+ accountDomain := viper.GetString(config.Keys.AccountDomain)
+ requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, accountDomain)
recorder := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(recorder)
@@ -130,7 +135,8 @@ func (suite *WebfingerGetTestSuite) TestFingerUserWithoutAcct() {
targetAccount := suite.testAccounts["local_account_1"]
// setup request -- leave out the 'acct:' prefix, which is prettymuch what pixelfed currently does
- requestPath := fmt.Sprintf("/%s?resource=%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, suite.config.Host)
+ host := viper.GetString(config.Keys.Host)
+ requestPath := fmt.Sprintf("/%s?resource=%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, host)
recorder := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(recorder)
diff --git a/internal/api/security/security.go b/internal/api/security/security.go
index 0379b2d53..1e55d5bc5 100644
--- a/internal/api/security/security.go
+++ b/internal/api/security/security.go
@@ -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/router"
@@ -32,15 +31,13 @@ const robotsPath = "/robots.txt"
// Module implements the ClientAPIModule interface for security middleware
type Module struct {
- config *config.Config
db db.DB
server oauth.Server
}
// New returns a new security module
-func New(config *config.Config, db db.DB, server oauth.Server) api.ClientModule {
+func New(db db.DB, server oauth.Server) api.ClientModule {
return &Module{
- config: config,
db: db,
server: server,
}
diff --git a/internal/cliactions/action.go b/internal/cliactions/action.go
deleted file mode 100644
index b72ae92b8..000000000
--- a/internal/cliactions/action.go
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package cliactions
-
-import (
- "context"
-
- "github.com/superseriousbusiness/gotosocial/internal/config"
-)
-
-// GTSAction defines one *action* that can be taken by the gotosocial cli command.
-// This can be either a long-running action (like server start) or something
-// shorter like db init or db inspect.
-type GTSAction func(context.Context, *config.Config) error
diff --git a/internal/cliactions/admin/account/account.go b/internal/cliactions/admin/account/account.go
deleted file mode 100644
index 5bdee9a41..000000000
--- a/internal/cliactions/admin/account/account.go
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package account
-
-import (
- "context"
- "errors"
- "fmt"
- "time"
-
- "github.com/superseriousbusiness/gotosocial/internal/cliactions"
- "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/validate"
- "golang.org/x/crypto/bcrypt"
-)
-
-// Create creates a new account in the database using the provided flags.
-var Create cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- dbConn, err := bundb.NewBunDBService(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
- }
-
- username, ok := c.AccountCLIFlags[config.UsernameFlag]
- if !ok {
- return errors.New("no username set")
- }
- if err := validate.Username(username); err != nil {
- return err
- }
-
- email, ok := c.AccountCLIFlags[config.EmailFlag]
- if !ok {
- return errors.New("no email set")
- }
- if err := validate.Email(email); err != nil {
- return err
- }
-
- password, ok := c.AccountCLIFlags[config.PasswordFlag]
- if !ok {
- return errors.New("no password set")
- }
- if err := validate.NewPassword(password); err != nil {
- return err
- }
-
- _, err = dbConn.NewSignup(ctx, username, "", false, email, password, nil, "", "", false, false)
- if err != nil {
- return err
- }
-
- return dbConn.Stop(ctx)
-}
-
-// Confirm sets a user to Approved, sets Email to the current UnconfirmedEmail value, and sets ConfirmedAt to now.
-var Confirm cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- dbConn, err := bundb.NewBunDBService(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
- }
-
- username, ok := c.AccountCLIFlags[config.UsernameFlag]
- if !ok {
- return errors.New("no username set")
- }
- if err := validate.Username(username); err != nil {
- return err
- }
-
- a, err := dbConn.GetLocalAccountByUsername(ctx, username)
- if err != nil {
- return err
- }
-
- u := &gtsmodel.User{}
- if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
- return err
- }
-
- u.Approved = true
- u.Email = u.UnconfirmedEmail
- u.ConfirmedAt = time.Now()
- if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
- return err
- }
-
- return dbConn.Stop(ctx)
-}
-
-// Promote sets a user to admin.
-var Promote cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- dbConn, err := bundb.NewBunDBService(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
- }
-
- username, ok := c.AccountCLIFlags[config.UsernameFlag]
- if !ok {
- return errors.New("no username set")
- }
- if err := validate.Username(username); err != nil {
- return err
- }
-
- a, err := dbConn.GetLocalAccountByUsername(ctx, username)
- if err != nil {
- return err
- }
-
- u := &gtsmodel.User{}
- if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
- return err
- }
- u.Admin = true
- if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
- return err
- }
-
- return dbConn.Stop(ctx)
-}
-
-// Demote sets admin on a user to false.
-var Demote cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- dbConn, err := bundb.NewBunDBService(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
- }
-
- username, ok := c.AccountCLIFlags[config.UsernameFlag]
- if !ok {
- return errors.New("no username set")
- }
- if err := validate.Username(username); err != nil {
- return err
- }
-
- a, err := dbConn.GetLocalAccountByUsername(ctx, username)
- if err != nil {
- return err
- }
-
- u := &gtsmodel.User{}
- if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
- return err
- }
- u.Admin = false
- if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
- return err
- }
-
- return dbConn.Stop(ctx)
-}
-
-// Disable sets Disabled to true on a user.
-var Disable cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- dbConn, err := bundb.NewBunDBService(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
- }
-
- username, ok := c.AccountCLIFlags[config.UsernameFlag]
- if !ok {
- return errors.New("no username set")
- }
- if err := validate.Username(username); err != nil {
- return err
- }
-
- a, err := dbConn.GetLocalAccountByUsername(ctx, username)
- if err != nil {
- return err
- }
-
- u := &gtsmodel.User{}
- if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
- return err
- }
- u.Disabled = true
- if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
- return err
- }
-
- return dbConn.Stop(ctx)
-}
-
-// Suspend suspends the target account, cleanly removing all of its media, followers, following, likes, statuses, etc.
-var Suspend cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- // TODO
- return nil
-}
-
-// Password sets the password of target account.
-var Password cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- dbConn, err := bundb.NewBunDBService(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
- }
-
- username, ok := c.AccountCLIFlags[config.UsernameFlag]
- if !ok {
- return errors.New("no username set")
- }
- if err := validate.Username(username); err != nil {
- return err
- }
-
- password, ok := c.AccountCLIFlags[config.PasswordFlag]
- if !ok {
- return errors.New("no password set")
- }
- if err := validate.NewPassword(password); err != nil {
- return err
- }
-
- a, err := dbConn.GetLocalAccountByUsername(ctx, username)
- if err != nil {
- return err
- }
-
- u := &gtsmodel.User{}
- if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
- return err
- }
-
- pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
- if err != nil {
- return fmt.Errorf("error hashing password: %s", err)
- }
-
- u.EncryptedPassword = string(pw)
-
- if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
- return err
- }
-
- return nil
-}
diff --git a/internal/cliactions/admin/trans/export.go b/internal/cliactions/admin/trans/export.go
deleted file mode 100644
index 89a22a357..000000000
--- a/internal/cliactions/admin/trans/export.go
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package trans
-
-import (
- "context"
- "errors"
- "fmt"
-
- "github.com/superseriousbusiness/gotosocial/internal/cliactions"
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/superseriousbusiness/gotosocial/internal/db/bundb"
- "github.com/superseriousbusiness/gotosocial/internal/trans"
-)
-
-// Export exports info from the database into a file
-var Export cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- dbConn, err := bundb.NewBunDBService(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
- }
-
- exporter := trans.NewExporter(dbConn)
-
- path, ok := c.ExportCLIFlags[config.TransPathFlag]
- if !ok {
- return errors.New("no path set")
- }
-
- if err := exporter.ExportMinimal(ctx, path); err != nil {
- return err
- }
-
- return dbConn.Stop(ctx)
-}
diff --git a/internal/cliactions/admin/trans/import.go b/internal/cliactions/admin/trans/import.go
deleted file mode 100644
index 9ab85d62f..000000000
--- a/internal/cliactions/admin/trans/import.go
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package trans
-
-import (
- "context"
- "errors"
- "fmt"
-
- "github.com/superseriousbusiness/gotosocial/internal/cliactions"
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/superseriousbusiness/gotosocial/internal/db/bundb"
- "github.com/superseriousbusiness/gotosocial/internal/trans"
-)
-
-// Import imports info from a file into the database
-var Import cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- dbConn, err := bundb.NewBunDBService(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
- }
-
- importer := trans.NewImporter(dbConn)
-
- path, ok := c.ExportCLIFlags[config.TransPathFlag]
- if !ok {
- return errors.New("no path set")
- }
-
- if err := importer.Import(ctx, path); err != nil {
- return err
- }
-
- return dbConn.Stop(ctx)
-}
diff --git a/internal/cliactions/server/server.go b/internal/cliactions/server/server.go
deleted file mode 100644
index 3e6acfe84..000000000
--- a/internal/cliactions/server/server.go
+++ /dev/null
@@ -1,204 +0,0 @@
-package server
-
-import (
- "context"
- "fmt"
- "net/http"
- "os"
- "os/signal"
- "syscall"
-
- "codeberg.org/gruf/go-store/kv"
- "github.com/sirupsen/logrus"
- "github.com/superseriousbusiness/gotosocial/internal/api"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/account"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/admin"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/app"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/auth"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/blocks"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/emoji"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/favourites"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/fileserver"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/filter"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/followrequest"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/instance"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/list"
- mediaModule "github.com/superseriousbusiness/gotosocial/internal/api/client/media"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/notification"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/search"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/status"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/streaming"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/timeline"
- userClient "github.com/superseriousbusiness/gotosocial/internal/api/client/user"
- "github.com/superseriousbusiness/gotosocial/internal/api/s2s/nodeinfo"
- "github.com/superseriousbusiness/gotosocial/internal/api/s2s/user"
- "github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger"
- "github.com/superseriousbusiness/gotosocial/internal/api/security"
- "github.com/superseriousbusiness/gotosocial/internal/cliactions"
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/superseriousbusiness/gotosocial/internal/db/bundb"
- "github.com/superseriousbusiness/gotosocial/internal/email"
- "github.com/superseriousbusiness/gotosocial/internal/federation"
- "github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb"
- "github.com/superseriousbusiness/gotosocial/internal/gotosocial"
- "github.com/superseriousbusiness/gotosocial/internal/media"
- "github.com/superseriousbusiness/gotosocial/internal/oauth"
- "github.com/superseriousbusiness/gotosocial/internal/oidc"
- "github.com/superseriousbusiness/gotosocial/internal/processing"
- "github.com/superseriousbusiness/gotosocial/internal/router"
- timelineprocessing "github.com/superseriousbusiness/gotosocial/internal/timeline"
- "github.com/superseriousbusiness/gotosocial/internal/transport"
- "github.com/superseriousbusiness/gotosocial/internal/typeutils"
- "github.com/superseriousbusiness/gotosocial/internal/web"
-)
-
-// Start creates and starts a gotosocial server
-var Start cliactions.GTSAction = func(ctx context.Context, c *config.Config) error {
- dbService, err := bundb.NewBunDBService(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
- }
-
- if err := dbService.CreateInstanceAccount(ctx); err != nil {
- return fmt.Errorf("error creating instance account: %s", err)
- }
-
- if err := dbService.CreateInstanceInstance(ctx); err != nil {
- return fmt.Errorf("error creating instance instance: %s", err)
- }
-
- federatingDB := federatingdb.New(dbService, c)
-
- router, err := router.New(ctx, c, dbService)
- if err != nil {
- return fmt.Errorf("error creating router: %s", err)
- }
-
- // build converters and util
- typeConverter := typeutils.NewConverter(c, dbService)
- timelineManager := timelineprocessing.NewManager(dbService, typeConverter, c)
-
- // Open the storage backend
- storage, err := kv.OpenFile(c.StorageConfig.BasePath, nil)
- if err != nil {
- return fmt.Errorf("error creating storage backend: %s", err)
- }
-
- // build backend handlers
- mediaHandler := media.New(c, dbService, storage)
- oauthServer := oauth.New(ctx, dbService)
- transportController := transport.NewController(c, dbService, &federation.Clock{}, http.DefaultClient)
- federator := federation.NewFederator(dbService, federatingDB, transportController, c, typeConverter, mediaHandler)
-
- // decide whether to create a noop email sender (won't send emails) or a real one
- var emailSender email.Sender
- if c.SMTPConfig.Host != "" {
- // host is defined so create a proper sender
- emailSender, err = email.NewSender(c)
- if err != nil {
- return fmt.Errorf("error creating email sender: %s", err)
- }
- } else {
- // no host is defined so create a noop sender
- emailSender, err = email.NewNoopSender(c.TemplateConfig.BaseDir, nil)
- if err != nil {
- return fmt.Errorf("error creating noop email sender: %s", err)
- }
- }
-
- // create and start the message processor using the other services we've created so far
- processor := processing.NewProcessor(c, typeConverter, federator, oauthServer, mediaHandler, storage, timelineManager, dbService, emailSender)
- if err := processor.Start(ctx); err != nil {
- return fmt.Errorf("error starting processor: %s", err)
- }
-
- idp, err := oidc.NewIDP(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating oidc idp: %s", err)
- }
-
- // build client api modules
- authModule := auth.New(c, dbService, oauthServer, idp)
- accountModule := account.New(c, processor)
- instanceModule := instance.New(c, processor)
- appsModule := app.New(c, processor)
- followRequestsModule := followrequest.New(c, processor)
- webfingerModule := webfinger.New(c, processor)
- nodeInfoModule := nodeinfo.New(c, processor)
- webBaseModule := web.New(c, processor)
- usersModule := user.New(c, processor)
- timelineModule := timeline.New(c, processor)
- notificationModule := notification.New(c, processor)
- searchModule := search.New(c, processor)
- filtersModule := filter.New(c, processor)
- emojiModule := emoji.New(c, processor)
- listsModule := list.New(c, processor)
- mm := mediaModule.New(c, processor)
- fileServerModule := fileserver.New(c, processor)
- adminModule := admin.New(c, processor)
- statusModule := status.New(c, processor)
- securityModule := security.New(c, dbService, oauthServer)
- streamingModule := streaming.New(c, processor)
- favouritesModule := favourites.New(c, processor)
- blocksModule := blocks.New(c, processor)
- userClientModule := userClient.New(c, processor)
-
- apis := []api.ClientModule{
- // modules with middleware go first
- securityModule,
- authModule,
-
- // now everything else
- webBaseModule,
- accountModule,
- instanceModule,
- appsModule,
- followRequestsModule,
- mm,
- fileServerModule,
- adminModule,
- statusModule,
- webfingerModule,
- nodeInfoModule,
- usersModule,
- timelineModule,
- notificationModule,
- searchModule,
- filtersModule,
- emojiModule,
- listsModule,
- streamingModule,
- favouritesModule,
- blocksModule,
- userClientModule,
- }
-
- for _, m := range apis {
- if err := m.Route(router); err != nil {
- return fmt.Errorf("routing error: %s", err)
- }
- }
-
- gts, err := gotosocial.NewServer(dbService, router, federator, c)
- if err != nil {
- return fmt.Errorf("error creating gotosocial service: %s", err)
- }
-
- if err := gts.Start(ctx); err != nil {
- return fmt.Errorf("error starting gotosocial service: %s", err)
- }
-
- // catch shutdown signals from the operating system
- sigs := make(chan os.Signal, 1)
- signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
- sig := <-sigs
- logrus.Infof("received signal %s, shutting down", sig)
-
- // close down all running services in order
- if err := gts.Stop(ctx); err != nil {
- return fmt.Errorf("error closing gotosocial service: %s", err)
- }
-
- logrus.Info("done! exiting...")
- return nil
-}
diff --git a/internal/cliactions/testrig/testrig.go b/internal/cliactions/testrig/testrig.go
deleted file mode 100644
index 5e55c3d03..000000000
--- a/internal/cliactions/testrig/testrig.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package testrig
-
-import (
- "bytes"
- "context"
- "fmt"
- "io/ioutil"
- "net/http"
- "os"
- "os/signal"
- "syscall"
-
- "github.com/sirupsen/logrus"
- "github.com/superseriousbusiness/gotosocial/internal/api"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/account"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/admin"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/app"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/auth"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/blocks"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/emoji"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/favourites"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/fileserver"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/filter"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/followrequest"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/instance"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/list"
- mediaModule "github.com/superseriousbusiness/gotosocial/internal/api/client/media"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/notification"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/search"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/status"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/streaming"
- "github.com/superseriousbusiness/gotosocial/internal/api/client/timeline"
- userClient "github.com/superseriousbusiness/gotosocial/internal/api/client/user"
- "github.com/superseriousbusiness/gotosocial/internal/api/s2s/nodeinfo"
- "github.com/superseriousbusiness/gotosocial/internal/api/s2s/user"
- "github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger"
- "github.com/superseriousbusiness/gotosocial/internal/api/security"
- "github.com/superseriousbusiness/gotosocial/internal/cliactions"
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/superseriousbusiness/gotosocial/internal/gotosocial"
- "github.com/superseriousbusiness/gotosocial/internal/oidc"
- "github.com/superseriousbusiness/gotosocial/internal/web"
- "github.com/superseriousbusiness/gotosocial/testrig"
-)
-
-// Start creates and starts a gotosocial testrig server
-var Start cliactions.GTSAction = func(ctx context.Context, _ *config.Config) error {
- testrig.InitTestLog()
-
- c := testrig.NewTestConfig()
- dbService := testrig.NewTestDB()
- testrig.StandardDBSetup(dbService, nil)
- router := testrig.NewTestRouter(dbService)
- storageBackend := testrig.NewTestStorage()
- testrig.StandardStorageSetup(storageBackend, "./testrig/media")
-
- // build backend handlers
- oauthServer := testrig.NewTestOauthServer(dbService)
- transportController := testrig.NewTestTransportController(testrig.NewMockHTTPClient(func(req *http.Request) (*http.Response, error) {
- r := ioutil.NopCloser(bytes.NewReader([]byte{}))
- return &http.Response{
- StatusCode: 200,
- Body: r,
- }, nil
- }), dbService)
- federator := testrig.NewTestFederator(dbService, transportController, storageBackend)
-
- emailSender := testrig.NewEmailSender("./web/template/", nil)
-
- processor := testrig.NewTestProcessor(dbService, storageBackend, federator, emailSender)
- if err := processor.Start(ctx); err != nil {
- return fmt.Errorf("error starting processor: %s", err)
- }
-
- idp, err := oidc.NewIDP(ctx, c)
- if err != nil {
- return fmt.Errorf("error creating oidc idp: %s", err)
- }
-
- // build client api modules
- authModule := auth.New(c, dbService, oauthServer, idp)
- accountModule := account.New(c, processor)
- instanceModule := instance.New(c, processor)
- appsModule := app.New(c, processor)
- followRequestsModule := followrequest.New(c, processor)
- webfingerModule := webfinger.New(c, processor)
- nodeInfoModule := nodeinfo.New(c, processor)
- webBaseModule := web.New(c, processor)
- usersModule := user.New(c, processor)
- timelineModule := timeline.New(c, processor)
- notificationModule := notification.New(c, processor)
- searchModule := search.New(c, processor)
- filtersModule := filter.New(c, processor)
- emojiModule := emoji.New(c, processor)
- listsModule := list.New(c, processor)
- mm := mediaModule.New(c, processor)
- fileServerModule := fileserver.New(c, processor)
- adminModule := admin.New(c, processor)
- statusModule := status.New(c, processor)
- securityModule := security.New(c, dbService, oauthServer)
- streamingModule := streaming.New(c, processor)
- favouritesModule := favourites.New(c, processor)
- blocksModule := blocks.New(c, processor)
- userClientModule := userClient.New(c, processor)
-
- apis := []api.ClientModule{
- // modules with middleware go first
- securityModule,
- authModule,
-
- // now everything else
- webBaseModule,
- accountModule,
- instanceModule,
- appsModule,
- followRequestsModule,
- mm,
- fileServerModule,
- adminModule,
- statusModule,
- webfingerModule,
- nodeInfoModule,
- usersModule,
- timelineModule,
- notificationModule,
- searchModule,
- filtersModule,
- emojiModule,
- listsModule,
- streamingModule,
- favouritesModule,
- blocksModule,
- userClientModule,
- }
-
- for _, m := range apis {
- if err := m.Route(router); err != nil {
- return fmt.Errorf("routing error: %s", err)
- }
- }
-
- gts, err := gotosocial.NewServer(dbService, router, federator, c)
- if err != nil {
- return fmt.Errorf("error creating gotosocial service: %s", err)
- }
-
- if err := gts.Start(ctx); err != nil {
- return fmt.Errorf("error starting gotosocial service: %s", err)
- }
-
- // catch shutdown signals from the operating system
- sigs := make(chan os.Signal, 1)
- signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
- sig := <-sigs
- logrus.Infof("received signal %s, shutting down", sig)
-
- testrig.StandardDBTeardown(dbService)
- testrig.StandardStorageTeardown(storageBackend)
-
- // close down all running services in order
- if err := gts.Stop(ctx); err != nil {
- return fmt.Errorf("error closing gotosocial service: %s", err)
- }
-
- logrus.Info("done! exiting...")
- return nil
-}
diff --git a/internal/config/accounts.go b/internal/config/accounts.go
deleted file mode 100644
index 3fc9e900e..000000000
--- a/internal/config/accounts.go
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package config
-
-// AccountsConfig contains configuration to do with creating accounts, new registrations, and defaults.
-type AccountsConfig struct {
- // Do we want people to be able to just submit sign up requests, or do we want invite only?
- OpenRegistration bool `yaml:"openRegistration"`
- // Do sign up requests require approval from an admin/moderator?
- RequireApproval bool `yaml:"requireApproval"`
- // Do we require a reason for a sign up or is an empty string OK?
- ReasonRequired bool `yaml:"reasonRequired"`
-}
diff --git a/internal/config/config.go b/internal/config/config.go
deleted file mode 100644
index eb9e6385b..000000000
--- a/internal/config/config.go
+++ /dev/null
@@ -1,622 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package config
-
-import (
- "errors"
- "fmt"
- "os"
-
- "gopkg.in/yaml.v2"
-)
-
-// Flags and usage strings for configuration.
-const (
- UsernameFlag = "username"
- UsernameUsage = "the username to create/delete/etc"
-
- EmailFlag = "email"
- EmailUsage = "the email address of this account"
-
- PasswordFlag = "password"
- PasswordUsage = "the password to set for this account"
-
- TransPathFlag = "path"
- TransPathUsage = "the path of the file to import from/export to"
-)
-
-// Config pulls together all the configuration needed to run gotosocial
-type Config struct {
- /*
- Parseable from .yaml configuration file.
- For long-running commands (server start etc).
- */
-
- LogLevel string `yaml:"logLevel"`
- ApplicationName string `yaml:"applicationName"`
- Host string `yaml:"host"`
- AccountDomain string `yaml:"accountDomain"`
- Protocol string `yaml:"protocol"`
- BindAddress string `yaml:"bindAddress"`
- Port int `yaml:"port"`
- TrustedProxies []string `yaml:"trustedProxies"`
- DBConfig *DBConfig `yaml:"db"`
- TemplateConfig *TemplateConfig `yaml:"template"`
- AccountsConfig *AccountsConfig `yaml:"accounts"`
- MediaConfig *MediaConfig `yaml:"media"`
- StorageConfig *StorageConfig `yaml:"storage"`
- StatusesConfig *StatusesConfig `yaml:"statuses"`
- LetsEncryptConfig *LetsEncryptConfig `yaml:"letsEncrypt"`
- OIDCConfig *OIDCConfig `yaml:"oidc"`
- SMTPConfig *SMTPConfig `yaml:"smtp"`
-
- /*
- Not parsed from .yaml configuration file.
- */
- AccountCLIFlags map[string]string
- ExportCLIFlags map[string]string
- SoftwareVersion string
-}
-
-// FromFile returns a new config from a file, or an error if something goes amiss.
-func FromFile(path string) (*Config, error) {
- if path != "" {
- c, err := loadFromFile(path)
- if err != nil {
- return nil, fmt.Errorf("error creating config: %s", err)
- }
- return c, nil
- }
- return Default(), nil
-}
-
-// loadFromFile takes a path to a yaml file and attempts to load a Config object from it
-func loadFromFile(path string) (*Config, error) {
- bytes, err := os.ReadFile(path)
- if err != nil {
- return nil, fmt.Errorf("could not read file at path %s: %s", path, err)
- }
-
- config := Default()
- if err := yaml.Unmarshal(bytes, config); err != nil {
- return nil, fmt.Errorf("could not unmarshal file at path %s: %s", path, err)
- }
-
- return config, nil
-}
-
-// ParseCLIFlags sets flags on the config using the provided Flags object
-func (c *Config) ParseCLIFlags(f KeyedFlags, version string) error {
- fn := GetFlagNames()
-
- // For all of these flags, we only want to set them on the config if:
- //
- // a) They haven't been set at all in the config file we already parsed,
- // and so we take the default from the flags object.
- //
- // b) They may have been set in the config, but they've *also* been set explicitly
- // as a command-line argument or an env variable, which takes priority.
-
- // general flags
- if f.IsSet(fn.LogLevel) {
- c.LogLevel = f.String(fn.LogLevel)
- }
-
- if f.IsSet(fn.ApplicationName) {
- c.ApplicationName = f.String(fn.ApplicationName)
- }
-
- if f.IsSet(fn.Host) {
- c.Host = f.String(fn.Host)
- }
- if c.Host == "" {
- return errors.New("host was not set")
- }
-
- if f.IsSet(fn.AccountDomain) {
- c.AccountDomain = f.String(fn.AccountDomain)
- }
- if c.AccountDomain == "" {
- c.AccountDomain = c.Host // default to whatever the host is, if this is empty
- }
-
- if f.IsSet(fn.Protocol) {
- c.Protocol = f.String(fn.Protocol)
- }
- if c.Protocol == "" {
- return errors.New("protocol was not set")
- }
-
- if f.IsSet(fn.BindAddress) {
- c.BindAddress = f.String(fn.BindAddress)
- }
-
- if f.IsSet(fn.Port) {
- c.Port = f.Int(fn.Port)
- }
-
- if f.IsSet(fn.TrustedProxies) {
- c.TrustedProxies = f.StringSlice(fn.TrustedProxies)
- }
-
- // db flags
- if f.IsSet(fn.DbType) {
- c.DBConfig.Type = f.String(fn.DbType)
- }
-
- if f.IsSet(fn.DbAddress) {
- c.DBConfig.Address = f.String(fn.DbAddress)
- }
-
- if f.IsSet(fn.DbPort) {
- c.DBConfig.Port = f.Int(fn.DbPort)
- }
-
- if f.IsSet(fn.DbUser) {
- c.DBConfig.User = f.String(fn.DbUser)
- }
-
- if f.IsSet(fn.DbPassword) {
- c.DBConfig.Password = f.String(fn.DbPassword)
- }
-
- if f.IsSet(fn.DbDatabase) {
- c.DBConfig.Database = f.String(fn.DbDatabase)
- }
-
- if f.IsSet(fn.DbTLSMode) {
- c.DBConfig.TLSMode = DBTLSMode(f.String(fn.DbTLSMode))
- }
-
- if f.IsSet(fn.DbTLSCACert) {
- c.DBConfig.TLSCACert = f.String(fn.DbTLSCACert)
- }
-
- // template flags
- if f.IsSet(fn.TemplateBaseDir) {
- c.TemplateConfig.BaseDir = f.String(fn.TemplateBaseDir)
- }
-
- // template flags
- if f.IsSet(fn.AssetBaseDir) {
- c.TemplateConfig.AssetBaseDir = f.String(fn.AssetBaseDir)
- }
-
- // accounts flags
- if f.IsSet(fn.AccountsOpenRegistration) {
- c.AccountsConfig.OpenRegistration = f.Bool(fn.AccountsOpenRegistration)
- }
-
- if f.IsSet(fn.AccountsApprovalRequired) {
- c.AccountsConfig.RequireApproval = f.Bool(fn.AccountsApprovalRequired)
- }
-
- // media flags
- if f.IsSet(fn.MediaMaxImageSize) {
- c.MediaConfig.MaxImageSize = f.Int(fn.MediaMaxImageSize)
- }
-
- if f.IsSet(fn.MediaMaxVideoSize) {
- c.MediaConfig.MaxVideoSize = f.Int(fn.MediaMaxVideoSize)
- }
-
- if f.IsSet(fn.MediaMinDescriptionChars) {
- c.MediaConfig.MinDescriptionChars = f.Int(fn.MediaMinDescriptionChars)
- }
-
- if f.IsSet(fn.MediaMaxDescriptionChars) {
- c.MediaConfig.MaxDescriptionChars = f.Int(fn.MediaMaxDescriptionChars)
- }
-
- // storage flags
- if f.IsSet(fn.StorageBackend) {
- c.StorageConfig.Backend = f.String(fn.StorageBackend)
- }
-
- if f.IsSet(fn.StorageBasePath) {
- c.StorageConfig.BasePath = f.String(fn.StorageBasePath)
- }
-
- if f.IsSet(fn.StorageServeProtocol) {
- c.StorageConfig.ServeProtocol = f.String(fn.StorageServeProtocol)
- }
-
- if f.IsSet(fn.StorageServeHost) {
- c.StorageConfig.ServeHost = f.String(fn.StorageServeHost)
- }
-
- if f.IsSet(fn.StorageServeBasePath) {
- c.StorageConfig.ServeBasePath = f.String(fn.StorageServeBasePath)
- }
-
- // statuses flags
- if f.IsSet(fn.StatusesMaxChars) {
- c.StatusesConfig.MaxChars = f.Int(fn.StatusesMaxChars)
- }
- if f.IsSet(fn.StatusesCWMaxChars) {
- c.StatusesConfig.CWMaxChars = f.Int(fn.StatusesCWMaxChars)
- }
- if f.IsSet(fn.StatusesPollMaxOptions) {
- c.StatusesConfig.PollMaxOptions = f.Int(fn.StatusesPollMaxOptions)
- }
- if f.IsSet(fn.StatusesPollOptionMaxChars) {
- c.StatusesConfig.PollOptionMaxChars = f.Int(fn.StatusesPollOptionMaxChars)
- }
- if f.IsSet(fn.StatusesMaxMediaFiles) {
- c.StatusesConfig.MaxMediaFiles = f.Int(fn.StatusesMaxMediaFiles)
- }
-
- // letsencrypt flags
- if f.IsSet(fn.LetsEncryptEnabled) {
- c.LetsEncryptConfig.Enabled = f.Bool(fn.LetsEncryptEnabled)
- }
-
- if f.IsSet(fn.LetsEncryptPort) {
- c.LetsEncryptConfig.Port = f.Int(fn.LetsEncryptPort)
- }
-
- if f.IsSet(fn.LetsEncryptCertDir) {
- c.LetsEncryptConfig.CertDir = f.String(fn.LetsEncryptCertDir)
- }
-
- if f.IsSet(fn.LetsEncryptEmailAddress) {
- c.LetsEncryptConfig.EmailAddress = f.String(fn.LetsEncryptEmailAddress)
- }
-
- // OIDC flags
- if f.IsSet(fn.OIDCEnabled) {
- c.OIDCConfig.Enabled = f.Bool(fn.OIDCEnabled)
- }
-
- if f.IsSet(fn.OIDCIdpName) {
- c.OIDCConfig.IDPName = f.String(fn.OIDCIdpName)
- }
-
- if f.IsSet(fn.OIDCSkipVerification) {
- c.OIDCConfig.SkipVerification = f.Bool(fn.OIDCSkipVerification)
- }
-
- if f.IsSet(fn.OIDCIssuer) {
- c.OIDCConfig.Issuer = f.String(fn.OIDCIssuer)
- }
-
- if f.IsSet(fn.OIDCClientID) {
- c.OIDCConfig.ClientID = f.String(fn.OIDCClientID)
- }
-
- if f.IsSet(fn.OIDCClientSecret) {
- c.OIDCConfig.ClientSecret = f.String(fn.OIDCClientSecret)
- }
-
- if f.IsSet(fn.OIDCScopes) {
- c.OIDCConfig.Scopes = f.StringSlice(fn.OIDCScopes)
- }
-
- // smtp flags
- if f.IsSet(fn.SMTPHost) {
- c.SMTPConfig.Host = f.String(fn.SMTPHost)
- }
-
- if f.IsSet(fn.SMTPPort) {
- c.SMTPConfig.Port = f.Int(fn.SMTPPort)
- }
-
- if f.IsSet(fn.SMTPUsername) {
- c.SMTPConfig.Username = f.String(fn.SMTPUsername)
- }
-
- if f.IsSet(fn.SMTPPassword) {
- c.SMTPConfig.Password = f.String(fn.SMTPPassword)
- }
-
- if f.IsSet(fn.SMTPFrom) {
- c.SMTPConfig.From = f.String(fn.SMTPFrom)
- }
-
- // command-specific flags
-
- // admin account CLI flags
- c.AccountCLIFlags[UsernameFlag] = f.String(UsernameFlag)
- c.AccountCLIFlags[EmailFlag] = f.String(EmailFlag)
- c.AccountCLIFlags[PasswordFlag] = f.String(PasswordFlag)
-
- // export CLI flags
- c.ExportCLIFlags[TransPathFlag] = f.String(TransPathFlag)
-
- c.SoftwareVersion = version
- return nil
-}
-
-// KeyedFlags is a wrapper for any type that can store keyed flags and give them back.
-// HINT: This works with a urfave cli context struct ;)
-type KeyedFlags interface {
- Bool(k string) bool
- String(k string) string
- StringSlice(k string) []string
- Int(k string) int
- IsSet(k string) bool
-}
-
-// Flags is used for storing the names of the various flags used for
-// initializing and storing urfavecli flag variables.
-type Flags struct {
- LogLevel string
- ApplicationName string
- ConfigPath string
- Host string
- AccountDomain string
- Protocol string
- BindAddress string
- Port string
- TrustedProxies string
-
- DbType string
- DbAddress string
- DbPort string
- DbUser string
- DbPassword string
- DbDatabase string
- DbTLSMode string
- DbTLSCACert string
-
- TemplateBaseDir string
- AssetBaseDir string
-
- AccountsOpenRegistration string
- AccountsApprovalRequired string
- AccountsReasonRequired string
-
- MediaMaxImageSize string
- MediaMaxVideoSize string
- MediaMinDescriptionChars string
- MediaMaxDescriptionChars string
-
- StorageBackend string
- StorageBasePath string
- StorageServeProtocol string
- StorageServeHost string
- StorageServeBasePath string
-
- StatusesMaxChars string
- StatusesCWMaxChars string
- StatusesPollMaxOptions string
- StatusesPollOptionMaxChars string
- StatusesMaxMediaFiles string
-
- LetsEncryptEnabled string
- LetsEncryptCertDir string
- LetsEncryptEmailAddress string
- LetsEncryptPort string
-
- OIDCEnabled string
- OIDCIdpName string
- OIDCSkipVerification string
- OIDCIssuer string
- OIDCClientID string
- OIDCClientSecret string
- OIDCScopes string
-
- SMTPHost string
- SMTPPort string
- SMTPUsername string
- SMTPPassword string
- SMTPFrom string
-}
-
-// Defaults contains all the default values for a gotosocial config
-type Defaults struct {
- LogLevel string
- ApplicationName string
- ConfigPath string
- Host string
- AccountDomain string
- Protocol string
- BindAddress string
- Port int
- TrustedProxies []string
- SoftwareVersion string
-
- DbType string
- DbAddress string
- DbPort int
- DbUser string
- DbPassword string
- DbDatabase string
- DBTlsMode string
- DBTlsCACert string
-
- TemplateBaseDir string
- AssetBaseDir string
-
- AccountsOpenRegistration bool
- AccountsRequireApproval bool
- AccountsReasonRequired bool
-
- MediaMaxImageSize int
- MediaMaxVideoSize int
- MediaMinDescriptionChars int
- MediaMaxDescriptionChars int
-
- StorageBackend string
- StorageBasePath string
- StorageServeProtocol string
- StorageServeHost string
- StorageServeBasePath string
-
- StatusesMaxChars int
- StatusesCWMaxChars int
- StatusesPollMaxOptions int
- StatusesPollOptionMaxChars int
- StatusesMaxMediaFiles int
-
- LetsEncryptEnabled bool
- LetsEncryptCertDir string
- LetsEncryptEmailAddress string
- LetsEncryptPort int
-
- OIDCEnabled bool
- OIDCIdpName string
- OIDCSkipVerification bool
- OIDCIssuer string
- OIDCClientID string
- OIDCClientSecret string
- OIDCScopes []string
-
- SMTPHost string
- SMTPPort int
- SMTPUsername string
- SMTPPassword string
- SMTPFrom string
-}
-
-// GetFlagNames returns a struct containing the names of the various flags used for
-// initializing and storing urfavecli flag variables.
-func GetFlagNames() Flags {
- return Flags{
- LogLevel: "log-level",
- ApplicationName: "application-name",
- ConfigPath: "config-path",
- Host: "host",
- AccountDomain: "account-domain",
- Protocol: "protocol",
- BindAddress: "bind-address",
- Port: "port",
- TrustedProxies: "trusted-proxies",
-
- DbType: "db-type",
- DbAddress: "db-address",
- DbPort: "db-port",
- DbUser: "db-user",
- DbPassword: "db-password",
- DbDatabase: "db-database",
- DbTLSMode: "db-tls-mode",
- DbTLSCACert: "db-tls-ca-cert",
-
- TemplateBaseDir: "template-basedir",
- AssetBaseDir: "asset-basedir",
-
- AccountsOpenRegistration: "accounts-open-registration",
- AccountsApprovalRequired: "accounts-approval-required",
- AccountsReasonRequired: "accounts-reason-required",
-
- MediaMaxImageSize: "media-max-image-size",
- MediaMaxVideoSize: "media-max-video-size",
- MediaMinDescriptionChars: "media-min-description-chars",
- MediaMaxDescriptionChars: "media-max-description-chars",
-
- StorageBackend: "storage-backend",
- StorageBasePath: "storage-base-path",
- StorageServeProtocol: "storage-serve-protocol",
- StorageServeHost: "storage-serve-host",
- StorageServeBasePath: "storage-serve-base-path",
-
- StatusesMaxChars: "statuses-max-chars",
- StatusesCWMaxChars: "statuses-cw-max-chars",
- StatusesPollMaxOptions: "statuses-poll-max-options",
- StatusesPollOptionMaxChars: "statuses-poll-option-max-chars",
- StatusesMaxMediaFiles: "statuses-max-media-files",
-
- LetsEncryptEnabled: "letsencrypt-enabled",
- LetsEncryptPort: "letsencrypt-port",
- LetsEncryptCertDir: "letsencrypt-cert-dir",
- LetsEncryptEmailAddress: "letsencrypt-email",
-
- OIDCEnabled: "oidc-enabled",
- OIDCIdpName: "oidc-idp-name",
- OIDCSkipVerification: "oidc-skip-verification",
- OIDCIssuer: "oidc-issuer",
- OIDCClientID: "oidc-client-id",
- OIDCClientSecret: "oidc-client-secret",
- OIDCScopes: "oidc-scopes",
-
- SMTPHost: "smtp-host",
- SMTPPort: "smtp-port",
- SMTPUsername: "smtp-username",
- SMTPPassword: "smtp-password",
- SMTPFrom: "smtp-from",
- }
-}
-
-// GetEnvNames returns a struct containing the names of the environment variable keys used for
-// initializing and storing urfavecli flag variables.
-func GetEnvNames() Flags {
- return Flags{
- LogLevel: "GTS_LOG_LEVEL",
- ApplicationName: "GTS_APPLICATION_NAME",
- ConfigPath: "GTS_CONFIG_PATH",
- Host: "GTS_HOST",
- AccountDomain: "GTS_ACCOUNT_DOMAIN",
- Protocol: "GTS_PROTOCOL",
- BindAddress: "GTS_BIND_ADDRESS",
- Port: "GTS_PORT",
- TrustedProxies: "GTS_TRUSTED_PROXIES",
-
- DbType: "GTS_DB_TYPE",
- DbAddress: "GTS_DB_ADDRESS",
- DbPort: "GTS_DB_PORT",
- DbUser: "GTS_DB_USER",
- DbPassword: "GTS_DB_PASSWORD",
- DbDatabase: "GTS_DB_DATABASE",
- DbTLSMode: "GTS_DB_TLS_MODE",
- DbTLSCACert: "GTS_DB_CA_CERT",
-
- TemplateBaseDir: "GTS_TEMPLATE_BASEDIR",
- AssetBaseDir: "GTS_ASSET_BASEDIR",
-
- AccountsOpenRegistration: "GTS_ACCOUNTS_OPEN_REGISTRATION",
- AccountsApprovalRequired: "GTS_ACCOUNTS_APPROVAL_REQUIRED",
- AccountsReasonRequired: "GTS_ACCOUNTS_REASON_REQUIRED",
-
- MediaMaxImageSize: "GTS_MEDIA_MAX_IMAGE_SIZE",
- MediaMaxVideoSize: "GTS_MEDIA_MAX_VIDEO_SIZE",
- MediaMinDescriptionChars: "GTS_MEDIA_MIN_DESCRIPTION_CHARS",
- MediaMaxDescriptionChars: "GTS_MEDIA_MAX_DESCRIPTION_CHARS",
-
- StorageBackend: "GTS_STORAGE_BACKEND",
- StorageBasePath: "GTS_STORAGE_BASE_PATH",
- StorageServeProtocol: "GTS_STORAGE_SERVE_PROTOCOL",
- StorageServeHost: "GTS_STORAGE_SERVE_HOST",
- StorageServeBasePath: "GTS_STORAGE_SERVE_BASE_PATH",
-
- StatusesMaxChars: "GTS_STATUSES_MAX_CHARS",
- StatusesCWMaxChars: "GTS_STATUSES_CW_MAX_CHARS",
- StatusesPollMaxOptions: "GTS_STATUSES_POLL_MAX_OPTIONS",
- StatusesPollOptionMaxChars: "GTS_STATUSES_POLL_OPTION_MAX_CHARS",
- StatusesMaxMediaFiles: "GTS_STATUSES_MAX_MEDIA_FILES",
-
- LetsEncryptEnabled: "GTS_LETSENCRYPT_ENABLED",
- LetsEncryptPort: "GTS_LETSENCRYPT_PORT",
- LetsEncryptCertDir: "GTS_LETSENCRYPT_CERT_DIR",
- LetsEncryptEmailAddress: "GTS_LETSENCRYPT_EMAIL",
-
- OIDCEnabled: "GTS_OIDC_ENABLED",
- OIDCIdpName: "GTS_OIDC_IDP_NAME",
- OIDCSkipVerification: "GTS_OIDC_SKIP_VERIFICATION",
- OIDCIssuer: "GTS_OIDC_ISSUER",
- OIDCClientID: "GTS_OIDC_CLIENT_ID",
- OIDCClientSecret: "GTS_OIDC_CLIENT_SECRET",
- OIDCScopes: "GTS_OIDC_SCOPES",
-
- SMTPHost: "SMTP_HOST",
- SMTPPort: "SMTP_PORT",
- SMTPUsername: "SMTP_USERNAME",
- SMTPPassword: "SMTP_PASSWORD",
- SMTPFrom: "SMTP_FROM",
- }
-}
diff --git a/internal/config/db.go b/internal/config/db.go
deleted file mode 100644
index ffdc07521..000000000
--- a/internal/config/db.go
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package config
-
-// DBConfig provides configuration options for the database connection
-type DBConfig struct {
- Type string `yaml:"type"`
- Address string `yaml:"address"`
- Port int `yaml:"port"`
- User string `yaml:"user"`
- Password string `yaml:"password"`
- Database string `yaml:"database"`
- ApplicationName string `yaml:"applicationName"`
- TLSMode DBTLSMode `yaml:"tlsMode"`
- TLSCACert string `yaml:"tlsCACert"`
-}
-
-// DBTLSMode describes a mode of connecting to a database with or without TLS.
-type DBTLSMode string
-
-// DBTLSModeDisable does not attempt to make a TLS connection to the database.
-var DBTLSModeDisable DBTLSMode = "disable"
-
-// DBTLSModeEnable attempts to make a TLS connection to the database, but doesn't fail if
-// the certificate passed by the database isn't verified.
-var DBTLSModeEnable DBTLSMode = "enable"
-
-// DBTLSModeRequire attempts to make a TLS connection to the database, and requires
-// that the certificate presented by the database is valid.
-var DBTLSModeRequire DBTLSMode = "require"
-
-// DBTLSModeUnset means that the TLS mode has not been set.
-var DBTLSModeUnset DBTLSMode
diff --git a/internal/config/default.go b/internal/config/default.go
deleted file mode 100644
index 6e8f63177..000000000
--- a/internal/config/default.go
+++ /dev/null
@@ -1,289 +0,0 @@
-package config
-
-import "github.com/coreos/go-oidc/v3/oidc"
-
-// TestDefault returns a default config for testing
-func TestDefault() *Config {
- defaults := GetTestDefaults()
- return &Config{
- LogLevel: defaults.LogLevel,
- ApplicationName: defaults.ApplicationName,
- Host: defaults.Host,
- AccountDomain: defaults.AccountDomain,
- Protocol: defaults.Protocol,
- BindAddress: defaults.BindAddress,
- Port: defaults.Port,
- TrustedProxies: defaults.TrustedProxies,
- SoftwareVersion: defaults.SoftwareVersion,
- DBConfig: &DBConfig{
- Type: defaults.DbType,
- Address: defaults.DbAddress,
- Port: defaults.DbPort,
- User: defaults.DbUser,
- Password: defaults.DbPassword,
- Database: defaults.DbDatabase,
- ApplicationName: defaults.ApplicationName,
- },
- TemplateConfig: &TemplateConfig{
- BaseDir: defaults.TemplateBaseDir,
- AssetBaseDir: defaults.AssetBaseDir,
- },
- AccountsConfig: &AccountsConfig{
- OpenRegistration: defaults.AccountsOpenRegistration,
- RequireApproval: defaults.AccountsRequireApproval,
- ReasonRequired: defaults.AccountsReasonRequired,
- },
- MediaConfig: &MediaConfig{
- MaxImageSize: defaults.MediaMaxImageSize,
- MaxVideoSize: defaults.MediaMaxVideoSize,
- MinDescriptionChars: defaults.MediaMinDescriptionChars,
- MaxDescriptionChars: defaults.MediaMaxDescriptionChars,
- },
- StorageConfig: &StorageConfig{
- Backend: defaults.StorageBackend,
- BasePath: defaults.StorageBasePath,
- ServeProtocol: defaults.StorageServeProtocol,
- ServeHost: defaults.StorageServeHost,
- ServeBasePath: defaults.StorageServeBasePath,
- },
- StatusesConfig: &StatusesConfig{
- MaxChars: defaults.StatusesMaxChars,
- CWMaxChars: defaults.StatusesCWMaxChars,
- PollMaxOptions: defaults.StatusesPollMaxOptions,
- PollOptionMaxChars: defaults.StatusesPollOptionMaxChars,
- MaxMediaFiles: defaults.StatusesMaxMediaFiles,
- },
- LetsEncryptConfig: &LetsEncryptConfig{
- Enabled: defaults.LetsEncryptEnabled,
- Port: defaults.LetsEncryptPort,
- CertDir: defaults.LetsEncryptCertDir,
- EmailAddress: defaults.LetsEncryptEmailAddress,
- },
- OIDCConfig: &OIDCConfig{
- Enabled: defaults.OIDCEnabled,
- IDPName: defaults.OIDCIdpName,
- SkipVerification: defaults.OIDCSkipVerification,
- Issuer: defaults.OIDCIssuer,
- ClientID: defaults.OIDCClientID,
- ClientSecret: defaults.OIDCClientSecret,
- Scopes: defaults.OIDCScopes,
- },
- SMTPConfig: &SMTPConfig{
- Host: defaults.SMTPHost,
- Port: defaults.SMTPPort,
- Username: defaults.SMTPUsername,
- Password: defaults.SMTPPassword,
- From: defaults.SMTPFrom,
- },
- }
-}
-
-// Default returns a config with all default values set
-func Default() *Config {
- defaults := GetDefaults()
- return &Config{
- LogLevel: defaults.LogLevel,
- ApplicationName: defaults.ApplicationName,
- Host: defaults.Host,
- Protocol: defaults.Protocol,
- BindAddress: defaults.BindAddress,
- Port: defaults.Port,
- TrustedProxies: defaults.TrustedProxies,
- SoftwareVersion: defaults.SoftwareVersion,
- DBConfig: &DBConfig{
- Type: defaults.DbType,
- Address: defaults.DbAddress,
- Port: defaults.DbPort,
- User: defaults.DbUser,
- Password: defaults.DbPassword,
- Database: defaults.DbDatabase,
- ApplicationName: defaults.ApplicationName,
- },
- TemplateConfig: &TemplateConfig{
- BaseDir: defaults.TemplateBaseDir,
- AssetBaseDir: defaults.AssetBaseDir,
- },
- AccountsConfig: &AccountsConfig{
- OpenRegistration: defaults.AccountsOpenRegistration,
- RequireApproval: defaults.AccountsRequireApproval,
- ReasonRequired: defaults.AccountsReasonRequired,
- },
- MediaConfig: &MediaConfig{
- MaxImageSize: defaults.MediaMaxImageSize,
- MaxVideoSize: defaults.MediaMaxVideoSize,
- MinDescriptionChars: defaults.MediaMinDescriptionChars,
- MaxDescriptionChars: defaults.MediaMaxDescriptionChars,
- },
- StorageConfig: &StorageConfig{
- Backend: defaults.StorageBackend,
- BasePath: defaults.StorageBasePath,
- ServeProtocol: defaults.StorageServeProtocol,
- ServeHost: defaults.StorageServeHost,
- ServeBasePath: defaults.StorageServeBasePath,
- },
- StatusesConfig: &StatusesConfig{
- MaxChars: defaults.StatusesMaxChars,
- CWMaxChars: defaults.StatusesCWMaxChars,
- PollMaxOptions: defaults.StatusesPollMaxOptions,
- PollOptionMaxChars: defaults.StatusesPollOptionMaxChars,
- MaxMediaFiles: defaults.StatusesMaxMediaFiles,
- },
- LetsEncryptConfig: &LetsEncryptConfig{
- Enabled: defaults.LetsEncryptEnabled,
- Port: defaults.LetsEncryptPort,
- CertDir: defaults.LetsEncryptCertDir,
- EmailAddress: defaults.LetsEncryptEmailAddress,
- },
- OIDCConfig: &OIDCConfig{
- Enabled: defaults.OIDCEnabled,
- IDPName: defaults.OIDCIdpName,
- SkipVerification: defaults.OIDCSkipVerification,
- Issuer: defaults.OIDCIssuer,
- ClientID: defaults.OIDCClientID,
- ClientSecret: defaults.OIDCClientSecret,
- Scopes: defaults.OIDCScopes,
- },
- SMTPConfig: &SMTPConfig{
- Host: defaults.SMTPHost,
- Port: defaults.SMTPPort,
- Username: defaults.SMTPUsername,
- Password: defaults.SMTPPassword,
- From: defaults.SMTPFrom,
- },
- AccountCLIFlags: make(map[string]string),
- ExportCLIFlags: make(map[string]string),
- }
-}
-
-// GetDefaults returns a populated Defaults struct with most of the values set to reasonable defaults.
-// Note that if you use this function, you still need to set Host and, if desired, ConfigPath.
-func GetDefaults() Defaults {
- return Defaults{
- LogLevel: "info",
- ApplicationName: "gotosocial",
- ConfigPath: "",
- Host: "",
- AccountDomain: "",
- Protocol: "https",
- BindAddress: "0.0.0.0",
- Port: 8080,
- TrustedProxies: []string{"127.0.0.1/32"}, // localhost
-
- DbType: "postgres",
- DbAddress: "localhost",
- DbPort: 5432,
- DbUser: "postgres",
- DbPassword: "postgres",
- DbDatabase: "postgres",
- DBTlsMode: "disable",
- DBTlsCACert: "",
-
- TemplateBaseDir: "./web/template/",
- AssetBaseDir: "./web/assets/",
-
- AccountsOpenRegistration: true,
- AccountsRequireApproval: true,
- AccountsReasonRequired: true,
-
- MediaMaxImageSize: 2097152, // 2mb
- MediaMaxVideoSize: 10485760, // 10mb
- MediaMinDescriptionChars: 0,
- MediaMaxDescriptionChars: 500,
-
- StorageBackend: "local",
- StorageBasePath: "/gotosocial/storage",
- StorageServeProtocol: "https",
- StorageServeHost: "localhost",
- StorageServeBasePath: "/fileserver",
-
- StatusesMaxChars: 5000,
- StatusesCWMaxChars: 100,
- StatusesPollMaxOptions: 6,
- StatusesPollOptionMaxChars: 50,
- StatusesMaxMediaFiles: 6,
-
- LetsEncryptEnabled: true,
- LetsEncryptPort: 80,
- LetsEncryptCertDir: "/gotosocial/storage/certs",
- LetsEncryptEmailAddress: "",
-
- OIDCEnabled: false,
- OIDCIdpName: "",
- OIDCSkipVerification: false,
- OIDCIssuer: "",
- OIDCClientID: "",
- OIDCClientSecret: "",
- OIDCScopes: []string{oidc.ScopeOpenID, "profile", "email", "groups"},
-
- SMTPHost: "",
- SMTPPort: 0,
- SMTPUsername: "",
- SMTPPassword: "",
- SMTPFrom: "GoToSocial",
- }
-}
-
-// GetTestDefaults returns a Defaults struct with values set that are suitable for local testing.
-func GetTestDefaults() Defaults {
- return Defaults{
- LogLevel: "trace",
- ApplicationName: "gotosocial",
- ConfigPath: "",
- Host: "localhost:8080",
- AccountDomain: "localhost:8080",
- Protocol: "http",
- BindAddress: "127.0.0.1",
- Port: 8080,
- TrustedProxies: []string{"127.0.0.1/32"},
-
- DbType: "sqlite",
- DbAddress: ":memory:",
- DbPort: 5432,
- DbUser: "postgres",
- DbPassword: "postgres",
- DbDatabase: "postgres",
-
- TemplateBaseDir: "./web/template/",
- AssetBaseDir: "./web/assets/",
-
- AccountsOpenRegistration: true,
- AccountsRequireApproval: true,
- AccountsReasonRequired: true,
-
- MediaMaxImageSize: 1048576, // 1mb
- MediaMaxVideoSize: 5242880, // 5mb
- MediaMinDescriptionChars: 0,
- MediaMaxDescriptionChars: 500,
-
- StorageBackend: "local",
- StorageBasePath: "/gotosocial/storage",
- StorageServeProtocol: "http",
- StorageServeHost: "localhost:8080",
- StorageServeBasePath: "/fileserver",
-
- StatusesMaxChars: 5000,
- StatusesCWMaxChars: 100,
- StatusesPollMaxOptions: 6,
- StatusesPollOptionMaxChars: 50,
- StatusesMaxMediaFiles: 6,
-
- LetsEncryptEnabled: false,
- LetsEncryptPort: 0,
- LetsEncryptCertDir: "",
- LetsEncryptEmailAddress: "",
-
- OIDCEnabled: false,
- OIDCIdpName: "",
- OIDCSkipVerification: false,
- OIDCIssuer: "",
- OIDCClientID: "",
- OIDCClientSecret: "",
- OIDCScopes: []string{oidc.ScopeOpenID, "profile", "email", "groups"},
-
- SMTPHost: "",
- SMTPPort: 0,
- SMTPUsername: "",
- SMTPPassword: "",
- SMTPFrom: "GoToSocial",
- }
-}
diff --git a/internal/config/defaults.go b/internal/config/defaults.go
new file mode 100644
index 000000000..01eef8c8c
--- /dev/null
+++ b/internal/config/defaults.go
@@ -0,0 +1,87 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package config
+
+import "github.com/coreos/go-oidc/v3/oidc"
+
+// Defaults returns a populated Values struct with most of the values set to reasonable defaults.
+// Note that if you use this, you still need to set Host and, if desired, ConfigPath.
+var Defaults = Values{
+ LogLevel: "info",
+ ApplicationName: "gotosocial",
+ ConfigPath: "",
+ Host: "",
+ AccountDomain: "",
+ Protocol: "https",
+ BindAddress: "0.0.0.0",
+ Port: 8080,
+ TrustedProxies: []string{"127.0.0.1/32"}, // localhost
+
+ DbType: "postgres",
+ DbAddress: "localhost",
+ DbPort: 5432,
+ DbUser: "postgres",
+ DbPassword: "postgres",
+ DbDatabase: "postgres",
+ DbTLSMode: "disable",
+ DbTLSCACert: "",
+
+ WebTemplateBaseDir: "./web/template/",
+ WebAssetBaseDir: "./web/assets/",
+
+ AccountsRegistrationOpen: true,
+ AccountsApprovalRequired: true,
+ AccountsReasonRequired: true,
+
+ MediaImageMaxSize: 2097152, // 2mb
+ MediaVideoMaxSize: 10485760, // 10mb
+ MediaDescriptionMinChars: 0,
+ MediaDescriptionMaxChars: 500,
+
+ StorageBackend: "local",
+ StorageBasePath: "/gotosocial/storage",
+ StorageServeProtocol: "https",
+ StorageServeHost: "localhost",
+ StorageServeBasePath: "/fileserver",
+
+ StatusesMaxChars: 5000,
+ StatusesCWMaxChars: 100,
+ StatusesPollMaxOptions: 6,
+ StatusesPollOptionMaxChars: 50,
+ StatusesMediaMaxFiles: 6,
+
+ LetsEncryptEnabled: true,
+ LetsEncryptPort: 80,
+ LetsEncryptCertDir: "/gotosocial/storage/certs",
+ LetsEncryptEmailAddress: "",
+
+ OIDCEnabled: false,
+ OIDCIdpName: "",
+ OIDCSkipVerification: false,
+ OIDCIssuer: "",
+ OIDCClientID: "",
+ OIDCClientSecret: "",
+ OIDCScopes: []string{oidc.ScopeOpenID, "profile", "email", "groups"},
+
+ SMTPHost: "",
+ SMTPPort: 0,
+ SMTPUsername: "",
+ SMTPPassword: "",
+ SMTPFrom: "GoToSocial",
+}
diff --git a/internal/config/template.go b/internal/config/file.go
index 9c524471c..62a3c0f6c 100644
--- a/internal/config/template.go
+++ b/internal/config/file.go
@@ -18,10 +18,21 @@
package config
-// TemplateConfig pertains to templating of web pages/email notifications and the like
-type TemplateConfig struct {
- // Directory from which gotosocial will attempt to load html templates (.tmpl files).
- BaseDir string `yaml:"baseDir"`
- // Directory from which static files are served
- AssetBaseDir string `yaml:"assetDir"`
+import (
+ "github.com/spf13/viper"
+)
+
+// ReadFromFile checks if there's already a path to the config file set in viper.
+// If there is, it will attempt to read the config file into viper.
+func ReadFromFile() error {
+ // config file stuff
+ // check if we have a config path set (either by cli arg or env var)
+ if configPath := viper.GetString(Keys.ConfigPath); configPath != "" {
+ viper.SetConfigFile(configPath)
+ if err := viper.ReadInConfig(); err != nil {
+ return err
+ }
+ }
+
+ return nil
}
diff --git a/internal/config/keys.go b/internal/config/keys.go
new file mode 100644
index 000000000..80ca36381
--- /dev/null
+++ b/internal/config/keys.go
@@ -0,0 +1,175 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package config
+
+// KeyNames is a struct that just contains the names of configuration keys.
+type KeyNames struct {
+ // root
+ LogLevel string
+ ConfigPath string
+
+ // general
+ ApplicationName string
+ Host string
+ AccountDomain string
+ Protocol string
+ BindAddress string
+ Port string
+ TrustedProxies string
+ SoftwareVersion string
+
+ // database
+ DbType string
+ DbAddress string
+ DbPort string
+ DbUser string
+ DbPassword string
+ DbDatabase string
+ DbTLSMode string
+ DbTLSCACert string
+
+ // template
+ WebTemplateBaseDir string
+ WebAssetBaseDir string
+
+ // accounts
+ AccountsRegistrationOpen string
+ AccountsApprovalRequired string
+ AccountsReasonRequired string
+
+ // media
+ MediaImageMaxSize string
+ MediaVideoMaxSize string
+ MediaDescriptionMinChars string
+ MediaDescriptionMaxChars string
+
+ // storage
+ StorageBackend string
+ StorageBasePath string
+ StorageServeProtocol string
+ StorageServeHost string
+ StorageServeBasePath string
+
+ // statuses
+ StatusesMaxChars string
+ StatusesCWMaxChars string
+ StatusesPollMaxOptions string
+ StatusesPollOptionMaxChars string
+ StatusesMediaMaxFiles string
+
+ // letsencrypt
+ LetsEncryptEnabled string
+ LetsEncryptCertDir string
+ LetsEncryptEmailAddress string
+ LetsEncryptPort string
+
+ // oidc
+ OIDCEnabled string
+ OIDCIdpName string
+ OIDCSkipVerification string
+ OIDCIssuer string
+ OIDCClientID string
+ OIDCClientSecret string
+ OIDCScopes string
+
+ // smtp
+ SMTPHost string
+ SMTPPort string
+ SMTPUsername string
+ SMTPPassword string
+ SMTPFrom string
+
+ // admin
+ AdminAccountUsername string
+ AdminAccountEmail string
+ AdminAccountPassword string
+ AdminTransPath string
+}
+
+// Keys contains the names of the various keys used for initializing and storing flag variables,
+// and retrieving values from the viper config store.
+var Keys = KeyNames{
+ LogLevel: "log-level",
+ ApplicationName: "application-name",
+ ConfigPath: "config-path",
+ Host: "host",
+ AccountDomain: "account-domain",
+ Protocol: "protocol",
+ BindAddress: "bind-address",
+ Port: "port",
+ TrustedProxies: "trusted-proxies",
+ SoftwareVersion: "software-version",
+
+ DbType: "db-type",
+ DbAddress: "db-address",
+ DbPort: "db-port",
+ DbUser: "db-user",
+ DbPassword: "db-password",
+ DbDatabase: "db-database",
+ DbTLSMode: "db-tls-mode",
+ DbTLSCACert: "db-tls-ca-cert",
+
+ WebTemplateBaseDir: "web-template-base-dir",
+ WebAssetBaseDir: "web-asset-base-dir",
+
+ AccountsRegistrationOpen: "accounts-registration-open",
+ AccountsApprovalRequired: "accounts-approval-required",
+ AccountsReasonRequired: "accounts-reason-required",
+
+ MediaImageMaxSize: "media-image-max-size",
+ MediaVideoMaxSize: "media-video-max-size",
+ MediaDescriptionMinChars: "media-description-min-chars",
+ MediaDescriptionMaxChars: "media-description-max-chars",
+
+ StorageBackend: "storage-backend",
+ StorageBasePath: "storage-base-path",
+ StorageServeProtocol: "storage-serve-protocol",
+ StorageServeHost: "storage-serve-host",
+ StorageServeBasePath: "storage-serve-base-path",
+
+ StatusesMaxChars: "statuses-max-chars",
+ StatusesCWMaxChars: "statuses-cw-max-chars",
+ StatusesPollMaxOptions: "statuses-poll-max-options",
+ StatusesPollOptionMaxChars: "statuses-poll-option-max-chars",
+ StatusesMediaMaxFiles: "statuses-media-max-files",
+
+ LetsEncryptEnabled: "letsencrypt-enabled",
+ LetsEncryptPort: "letsencrypt-port",
+ LetsEncryptCertDir: "letsencrypt-cert-dir",
+ LetsEncryptEmailAddress: "letsencrypt-email-address",
+
+ OIDCEnabled: "oidc-enabled",
+ OIDCIdpName: "oidc-idp-name",
+ OIDCSkipVerification: "oidc-skip-verification",
+ OIDCIssuer: "oidc-issuer",
+ OIDCClientID: "oidc-client-id",
+ OIDCClientSecret: "oidc-client-secret",
+ OIDCScopes: "oidc-scopes",
+
+ SMTPHost: "smtp-host",
+ SMTPPort: "smtp-port",
+ SMTPUsername: "smtp-username",
+ SMTPPassword: "smtp-password",
+ SMTPFrom: "smtp-from",
+
+ AdminAccountUsername: "username",
+ AdminAccountEmail: "email",
+ AdminAccountPassword: "password",
+ AdminTransPath: "path",
+}
diff --git a/internal/config/letsencrypt.go b/internal/config/letsencrypt.go
deleted file mode 100644
index a71172635..000000000
--- a/internal/config/letsencrypt.go
+++ /dev/null
@@ -1,13 +0,0 @@
-package config
-
-// LetsEncryptConfig wraps everything needed to manage letsencrypt certificates from within gotosocial.
-type LetsEncryptConfig struct {
- // Should letsencrypt certificate fetching be enabled?
- Enabled bool `yaml:"enabled"`
- // What port should the server listen for letsencrypt challenges on?
- Port int `yaml:"port"`
- // Where should certificates be stored?
- CertDir string `yaml:"certDir"`
- // Email address to pass to letsencrypt for notifications about certificate expiry etc.
- EmailAddress string `yaml:"emailAddress"`
-}
diff --git a/internal/config/media.go b/internal/config/media.go
deleted file mode 100644
index 136dba528..000000000
--- a/internal/config/media.go
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package config
-
-// MediaConfig contains configuration for receiving and parsing media files and attachments
-type MediaConfig struct {
- // Max size of uploaded images in bytes
- MaxImageSize int `yaml:"maxImageSize"`
- // Max size of uploaded video in bytes
- MaxVideoSize int `yaml:"maxVideoSize"`
- // Minimum amount of chars required in an image description
- MinDescriptionChars int `yaml:"minDescriptionChars"`
- // Max amount of chars allowed in an image description
- MaxDescriptionChars int `yaml:"maxDescriptionChars"`
-}
diff --git a/internal/config/oidc.go b/internal/config/oidc.go
deleted file mode 100644
index 06158bbb7..000000000
--- a/internal/config/oidc.go
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package config
-
-// OIDCConfig contains configuration values for openID connect (oauth) authorization by an external service such as Dex.
-type OIDCConfig struct {
- Enabled bool `yaml:"enabled"`
- IDPName string `yaml:"idpName"`
- SkipVerification bool `yaml:"skipVerification"`
- Issuer string `yaml:"issuer"`
- ClientID string `yaml:"clientID"`
- ClientSecret string `yaml:"clientSecret"`
- Scopes []string `yaml:"scopes"`
-}
diff --git a/internal/config/statuses.go b/internal/config/statuses.go
deleted file mode 100644
index fbb5225b4..000000000
--- a/internal/config/statuses.go
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package config
-
-// StatusesConfig pertains to posting/deleting/interacting with statuses
-type StatusesConfig struct {
- // Maximum amount of characters allowed in a status, excluding CW
- MaxChars int `yaml:"max_chars"`
- // Maximum amount of characters allowed in a content-warning/spoiler field
- CWMaxChars int `yaml:"cw_max_chars"`
- // Maximum number of options allowed in a poll
- PollMaxOptions int `yaml:"poll_max_options"`
- // Maximum characters allowed per poll option
- PollOptionMaxChars int `yaml:"poll_option_max_chars"`
- // Maximum amount of media files allowed to be attached to one status
- MaxMediaFiles int `yaml:"max_media_files"`
-}
diff --git a/internal/config/storage.go b/internal/config/storage.go
deleted file mode 100644
index 4a8ff79e4..000000000
--- a/internal/config/storage.go
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package config
-
-// StorageConfig contains configuration for storage and serving of media files and attachments
-type StorageConfig struct {
- // Type of storage backend to use: currently only 'local' is supported.
- // TODO: add S3 support here.
- Backend string `yaml:"backend"`
-
- // The base path for storing things. Should be an already-existing directory.
- BasePath string `yaml:"basePath"`
-
- // Protocol to use when *serving* media files from storage
- ServeProtocol string `yaml:"serveProtocol"`
- // Host to use when *serving* media files from storage
- ServeHost string `yaml:"serveHost"`
- // Base path to use when *serving* media files from storage
- ServeBasePath string `yaml:"serveBasePath"`
-}
diff --git a/internal/config/values.go b/internal/config/values.go
new file mode 100644
index 000000000..387f934d8
--- /dev/null
+++ b/internal/config/values.go
@@ -0,0 +1,90 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package config
+
+// Values contains contains the type of each configuration value.
+type Values struct {
+ LogLevel string
+ ApplicationName string
+ ConfigPath string
+ Host string
+ AccountDomain string
+ Protocol string
+ BindAddress string
+ Port int
+ TrustedProxies []string
+ SoftwareVersion string
+
+ DbType string
+ DbAddress string
+ DbPort int
+ DbUser string
+ DbPassword string
+ DbDatabase string
+ DbTLSMode string
+ DbTLSCACert string
+
+ WebTemplateBaseDir string
+ WebAssetBaseDir string
+
+ AccountsRegistrationOpen bool
+ AccountsApprovalRequired bool
+ AccountsReasonRequired bool
+
+ MediaImageMaxSize int
+ MediaVideoMaxSize int
+ MediaDescriptionMinChars int
+ MediaDescriptionMaxChars int
+
+ StorageBackend string
+ StorageBasePath string
+ StorageServeProtocol string
+ StorageServeHost string
+ StorageServeBasePath string
+
+ StatusesMaxChars int
+ StatusesCWMaxChars int
+ StatusesPollMaxOptions int
+ StatusesPollOptionMaxChars int
+ StatusesMediaMaxFiles int
+
+ LetsEncryptEnabled bool
+ LetsEncryptCertDir string
+ LetsEncryptEmailAddress string
+ LetsEncryptPort int
+
+ OIDCEnabled bool
+ OIDCIdpName string
+ OIDCSkipVerification bool
+ OIDCIssuer string
+ OIDCClientID string
+ OIDCClientSecret string
+ OIDCScopes []string
+
+ SMTPHost string
+ SMTPPort int
+ SMTPUsername string
+ SMTPPassword string
+ SMTPFrom string
+
+ AdminAccountUsername string
+ AdminAccountEmail string
+ AdminAccountPassword string
+ AdminTransPath string
+}
diff --git a/internal/config/smtp.go b/internal/config/viper.go
index daa4967bf..f53ef78d0 100644
--- a/internal/config/smtp.go
+++ b/internal/config/viper.go
@@ -18,16 +18,25 @@
package config
-// SMTPConfig holds configuration for sending emails using the smtp protocol.
-type SMTPConfig struct {
- // Host of the smtp server.
- Host string `yaml:"host"`
- // Port of the smtp server.
- Port int `yaml:"port"`
- // Username to use when authenticating with the smtp server.
- Username string `yaml:"username"`
- // Password to use when authenticating with the smtp server.
- Password string `yaml:"password"`
- // From address to use when sending emails.
- From string `yaml:"from"`
+import (
+ "strings"
+
+ "github.com/spf13/pflag"
+ "github.com/spf13/viper"
+)
+
+func InitViper(f *pflag.FlagSet) error {
+ // environment variable stuff
+ // flag 'some-flag-name' becomes env var 'GTS_SOME_FLAG_NAME'
+ viper.SetEnvPrefix("gts")
+ viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
+ viper.AutomaticEnv()
+
+ // flag stuff
+ // bind all of the flags in flagset to viper so that we can retrieve their values from the viper store
+ if err := viper.BindPFlags(f); err != nil {
+ return err
+ }
+
+ return nil
}
diff --git a/internal/db/bundb/account.go b/internal/db/bundb/account.go
index 9c9dcfc6a..ab6ec2b7c 100644
--- a/internal/db/bundb/account.go
+++ b/internal/db/bundb/account.go
@@ -24,6 +24,7 @@ import (
"fmt"
"time"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/cache"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
@@ -32,9 +33,8 @@ import (
)
type accountDB struct {
- config *config.Config
- conn *DBConn
- cache *cache.AccountCache
+ conn *DBConn
+ cache *cache.AccountCache
}
func (a *accountDB) newAccountQ(account *gtsmodel.Account) *bun.SelectQuery {
@@ -132,8 +132,9 @@ func (a *accountDB) GetInstanceAccount(ctx context.Context, domain string) (*gts
Where("account.username = ?", domain).
Where("account.domain = ?", domain)
} else {
+ host := viper.GetString(config.Keys.Host)
q = q.
- Where("account.username = ?", a.config.Host).
+ Where("account.username = ?", host).
WhereGroup(" AND ", whereEmptyOrNull("domain"))
}
diff --git a/internal/db/bundb/admin.go b/internal/db/bundb/admin.go
index accdf7e53..4b05fdd56 100644
--- a/internal/db/bundb/admin.go
+++ b/internal/db/bundb/admin.go
@@ -30,6 +30,7 @@ import (
"time"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/config"
@@ -41,8 +42,7 @@ import (
)
type adminDB struct {
- config *config.Config
- conn *DBConn
+ conn *DBConn
}
func (a *adminDB) IsUsernameAvailable(ctx context.Context, username string) (bool, db.Error) {
@@ -101,7 +101,7 @@ func (a *adminDB) NewSignup(ctx context.Context, username string, reason string,
Scan(ctx)
if err != nil {
// we just don't have an account yet create one
- newAccountURIs := util.GenerateURIsForAccount(username, a.config.Protocol, a.config.Host)
+ newAccountURIs := util.GenerateURIsForAccount(username)
newAccountID, err := id.NewRandomULID()
if err != nil {
return nil, err
@@ -176,7 +176,7 @@ func (a *adminDB) NewSignup(ctx context.Context, username string, reason string,
}
func (a *adminDB) CreateInstanceAccount(ctx context.Context) db.Error {
- username := a.config.Host
+ username := viper.GetString(config.Keys.Host)
q := a.conn.
NewSelect().
@@ -204,10 +204,10 @@ func (a *adminDB) CreateInstanceAccount(ctx context.Context) db.Error {
return err
}
- newAccountURIs := util.GenerateURIsForAccount(username, a.config.Protocol, a.config.Host)
+ newAccountURIs := util.GenerateURIsForAccount(username)
acct := &gtsmodel.Account{
ID: aID,
- Username: a.config.Host,
+ Username: username,
DisplayName: username,
URL: newAccountURIs.UserURL,
PrivateKey: key,
@@ -235,13 +235,14 @@ func (a *adminDB) CreateInstanceAccount(ctx context.Context) db.Error {
}
func (a *adminDB) CreateInstanceInstance(ctx context.Context) db.Error {
- domain := a.config.Host
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
// check if instance entry already exists
q := a.conn.
NewSelect().
Model(&gtsmodel.Instance{}).
- Where("domain = ?", domain)
+ Where("domain = ?", host)
exists, err := a.conn.Exists(ctx, q)
if err != nil {
@@ -259,9 +260,9 @@ func (a *adminDB) CreateInstanceInstance(ctx context.Context) db.Error {
i := &gtsmodel.Instance{
ID: iID,
- Domain: domain,
- Title: domain,
- URI: fmt.Sprintf("%s://%s", a.config.Protocol, a.config.Host),
+ Domain: host,
+ Title: host,
+ URI: fmt.Sprintf("%s://%s", protocol, host),
}
insertQ := a.conn.
@@ -273,6 +274,6 @@ func (a *adminDB) CreateInstanceInstance(ctx context.Context) db.Error {
return a.conn.ProcessError(err)
}
- logrus.Infof("created instance instance %s with id %s", domain, i.ID)
+ logrus.Infof("created instance instance %s with id %s", host, i.ID)
return nil
}
diff --git a/internal/db/bundb/basic.go b/internal/db/bundb/basic.go
index 2ff8dcb9b..a4cff4202 100644
--- a/internal/db/bundb/basic.go
+++ b/internal/db/bundb/basic.go
@@ -24,15 +24,13 @@ import (
"github.com/sirupsen/logrus"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/uptrace/bun"
)
type basicDB struct {
- config *config.Config
- conn *DBConn
+ conn *DBConn
}
func (b *basicDB) Put(ctx context.Context, i interface{}) db.Error {
diff --git a/internal/db/bundb/bundb.go b/internal/db/bundb/bundb.go
index 4634f1981..bb159fad8 100644
--- a/internal/db/bundb/bundb.go
+++ b/internal/db/bundb/bundb.go
@@ -35,6 +35,7 @@ import (
"github.com/jackc/pgx/v4"
"github.com/jackc/pgx/v4/stdlib"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/cache"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
@@ -52,6 +53,17 @@ import (
const (
dbTypePostgres = "postgres"
dbTypeSqlite = "sqlite"
+
+ // dbTLSModeDisable does not attempt to make a TLS connection to the database.
+ dbTLSModeDisable = "disable"
+ // dbTLSModeEnable attempts to make a TLS connection to the database, but doesn't fail if
+ // the certificate passed by the database isn't verified.
+ dbTLSModeEnable = "enable"
+ // dbTLSModeRequire attempts to make a TLS connection to the database, and requires
+ // that the certificate presented by the database is valid.
+ dbTLSModeRequire = "require"
+ // dbTLSModeUnset means that the TLS mode has not been set.
+ dbTLSModeUnset = ""
)
var registerTables = []interface{}{
@@ -73,8 +85,7 @@ type bunDBService struct {
db.Session
db.Status
db.Timeline
- config *config.Config
- conn *DBConn
+ conn *DBConn
}
func doMigration(ctx context.Context, db *bun.DB) error {
@@ -105,22 +116,24 @@ func doMigration(ctx context.Context, db *bun.DB) error {
// NewBunDBService returns a bunDB derived from the provided config, which implements the go-fed DB interface.
// Under the hood, it uses https://github.com/uptrace/bun to create and maintain a database connection.
-func NewBunDBService(ctx context.Context, c *config.Config) (db.DB, error) {
+func NewBunDBService(ctx context.Context) (db.DB, error) {
var conn *DBConn
var err error
- switch strings.ToLower(c.DBConfig.Type) {
+ dbType := strings.ToLower(viper.GetString(config.Keys.DbType))
+
+ switch dbType {
case dbTypePostgres:
- conn, err = pgConn(ctx, c)
+ conn, err = pgConn(ctx)
if err != nil {
return nil, err
}
case dbTypeSqlite:
- conn, err = sqliteConn(ctx, c)
+ conn, err = sqliteConn(ctx)
if err != nil {
return nil, err
}
default:
- return nil, fmt.Errorf("database type %s not supported for bundb", strings.ToLower(c.DBConfig.Type))
+ return nil, fmt.Errorf("database type %s not supported for bundb", dbType)
}
// add a hook to just log queries and the time they take
@@ -142,76 +155,66 @@ func NewBunDBService(ctx context.Context, c *config.Config) (db.DB, error) {
return nil, fmt.Errorf("db migration error: %s", err)
}
- accounts := &accountDB{config: c, conn: conn, cache: cache.NewAccountCache()}
+ accounts := &accountDB{conn: conn, cache: cache.NewAccountCache()}
ps := &bunDBService{
Account: accounts,
Admin: &adminDB{
- config: c,
- conn: conn,
+ conn: conn,
},
Basic: &basicDB{
- config: c,
- conn: conn,
+ conn: conn,
},
Domain: &domainDB{
- config: c,
- conn: conn,
+ conn: conn,
},
Instance: &instanceDB{
- config: c,
- conn: conn,
+ conn: conn,
},
Media: &mediaDB{
- config: c,
- conn: conn,
+ conn: conn,
},
Mention: &mentionDB{
- config: c,
- conn: conn,
- cache: ttlcache.NewCache(),
+ conn: conn,
+ cache: ttlcache.NewCache(),
},
Notification: &notificationDB{
- config: c,
- conn: conn,
- cache: ttlcache.NewCache(),
+ conn: conn,
+ cache: ttlcache.NewCache(),
},
Relationship: &relationshipDB{
- config: c,
- conn: conn,
+ conn: conn,
},
Session: &sessionDB{
- config: c,
- conn: conn,
+ conn: conn,
},
Status: &statusDB{
- config: c,
conn: conn,
cache: cache.NewStatusCache(),
accounts: accounts,
},
Timeline: &timelineDB{
- config: c,
- conn: conn,
+ conn: conn,
},
- config: c,
- conn: conn,
+ conn: conn,
}
// we can confidently return this useable service now
return ps, nil
}
-func sqliteConn(ctx context.Context, c *config.Config) (*DBConn, error) {
+func sqliteConn(ctx context.Context) (*DBConn, error) {
+ dbAddress := viper.GetString(config.Keys.DbAddress)
+
// Drop anything fancy from DB address
- c.DBConfig.Address = strings.Split(c.DBConfig.Address, "?")[0]
- c.DBConfig.Address = strings.TrimPrefix(c.DBConfig.Address, "file:")
+ dbAddress = strings.Split(dbAddress, "?")[0]
+ dbAddress = strings.TrimPrefix(dbAddress, "file:")
// Append our own SQLite preferences
- c.DBConfig.Address = "file:" + c.DBConfig.Address + "?cache=shared"
+ dbAddress = "file:" + dbAddress + "?cache=shared"
// Open new DB instance
- sqldb, err := sql.Open("sqlite", c.DBConfig.Address)
+ sqldb, err := sql.Open("sqlite", dbAddress)
if err != nil {
if errWithCode, ok := err.(*sqlite.Error); ok {
err = errors.New(sqlite.ErrorCodeString[errWithCode.Code()])
@@ -221,7 +224,7 @@ func sqliteConn(ctx context.Context, c *config.Config) (*DBConn, error) {
tweakConnectionValues(sqldb)
- if c.DBConfig.Address == "file::memory:?cache=shared" {
+ if dbAddress == "file::memory:?cache=shared" {
logrus.Warn("sqlite in-memory database should only be used for debugging")
// don't close connections on disconnect -- otherwise
// the SQLite database will be deleted when there
@@ -243,8 +246,8 @@ func sqliteConn(ctx context.Context, c *config.Config) (*DBConn, error) {
return conn, nil
}
-func pgConn(ctx context.Context, c *config.Config) (*DBConn, error) {
- opts, err := deriveBunDBPGOptions(c)
+func pgConn(ctx context.Context) (*DBConn, error) {
+ opts, err := deriveBunDBPGOptions()
if err != nil {
return nil, fmt.Errorf("could not create bundb postgres options: %s", err)
}
@@ -270,54 +273,63 @@ func pgConn(ctx context.Context, c *config.Config) (*DBConn, error) {
// deriveBunDBPGOptions takes an application config and returns either a ready-to-use set of options
// with sensible defaults, or an error if it's not satisfied by the provided config.
-func deriveBunDBPGOptions(c *config.Config) (*pgx.ConnConfig, error) {
- if strings.ToUpper(c.DBConfig.Type) != db.DBTypePostgres {
- return nil, fmt.Errorf("expected db type of %s but got %s", db.DBTypePostgres, c.DBConfig.Type)
+func deriveBunDBPGOptions() (*pgx.ConnConfig, error) {
+ keys := config.Keys
+
+ if strings.ToUpper(viper.GetString(keys.DbType)) != db.DBTypePostgres {
+ return nil, fmt.Errorf("expected db type of %s but got %s", db.DBTypePostgres, viper.GetString(keys.DbType))
}
// validate port
- if c.DBConfig.Port == 0 {
+ port := viper.GetInt(keys.DbPort)
+ if port == 0 {
return nil, errors.New("no port set")
}
// validate address
- if c.DBConfig.Address == "" {
+ address := viper.GetString(keys.DbAddress)
+ if address == "" {
return nil, errors.New("no address set")
}
// validate username
- if c.DBConfig.User == "" {
+ username := viper.GetString(keys.DbUser)
+ if username == "" {
return nil, errors.New("no user set")
}
// validate that there's a password
- if c.DBConfig.Password == "" {
+ password := viper.GetString(keys.DbPassword)
+ if password == "" {
return nil, errors.New("no password set")
}
// validate database
- if c.DBConfig.Database == "" {
+ database := viper.GetString(keys.DbDatabase)
+ if database == "" {
return nil, errors.New("no database set")
}
var tlsConfig *tls.Config
- switch c.DBConfig.TLSMode {
- case config.DBTLSModeDisable, config.DBTLSModeUnset:
+ tlsMode := viper.GetString(keys.DbTLSMode)
+ switch tlsMode {
+ case dbTLSModeDisable, dbTLSModeUnset:
break // nothing to do
- case config.DBTLSModeEnable:
+ case dbTLSModeEnable:
/* #nosec G402 */
tlsConfig = &tls.Config{
InsecureSkipVerify: true,
}
- case config.DBTLSModeRequire:
+ case dbTLSModeRequire:
tlsConfig = &tls.Config{
InsecureSkipVerify: false,
- ServerName: c.DBConfig.Address,
+ ServerName: viper.GetString(keys.DbAddress),
MinVersion: tls.VersionTLS12,
}
}
- if tlsConfig != nil && c.DBConfig.TLSCACert != "" {
+ caCertPath := viper.GetString(keys.DbTLSCACert)
+ if tlsConfig != nil && caCertPath != "" {
// load the system cert pool first -- we'll append the given CA cert to this
certPool, err := x509.SystemCertPool()
if err != nil {
@@ -325,24 +337,24 @@ func deriveBunDBPGOptions(c *config.Config) (*pgx.ConnConfig, error) {
}
// open the file itself and make sure there's something in it
- caCertBytes, err := os.ReadFile(c.DBConfig.TLSCACert)
+ caCertBytes, err := os.ReadFile(caCertPath)
if err != nil {
- return nil, fmt.Errorf("error opening CA certificate at %s: %s", c.DBConfig.TLSCACert, err)
+ return nil, fmt.Errorf("error opening CA certificate at %s: %s", caCertPath, err)
}
if len(caCertBytes) == 0 {
- return nil, fmt.Errorf("ca cert at %s was empty", c.DBConfig.TLSCACert)
+ return nil, fmt.Errorf("ca cert at %s was empty", caCertPath)
}
// make sure we have a PEM block
caPem, _ := pem.Decode(caCertBytes)
if caPem == nil {
- return nil, fmt.Errorf("could not parse cert at %s into PEM", c.DBConfig.TLSCACert)
+ return nil, fmt.Errorf("could not parse cert at %s into PEM", caCertPath)
}
// parse the PEM block into the certificate
caCert, err := x509.ParseCertificate(caPem.Bytes)
if err != nil {
- return nil, fmt.Errorf("could not parse cert at %s into x509 certificate: %s", c.DBConfig.TLSCACert, err)
+ return nil, fmt.Errorf("could not parse cert at %s into x509 certificate: %s", caCertPath, err)
}
// we're happy, add it to the existing pool and then use this pool in our tls config
@@ -351,14 +363,14 @@ func deriveBunDBPGOptions(c *config.Config) (*pgx.ConnConfig, error) {
}
cfg, _ := pgx.ParseConfig("")
- cfg.Host = c.DBConfig.Address
- cfg.Port = uint16(c.DBConfig.Port)
- cfg.User = c.DBConfig.User
- cfg.Password = c.DBConfig.Password
+ cfg.Host = address
+ cfg.Port = uint16(port)
+ cfg.User = username
+ cfg.Password = password
cfg.TLSConfig = tlsConfig
- cfg.Database = c.DBConfig.Database
+ cfg.Database = database
cfg.PreferSimpleProtocol = true
- cfg.RuntimeParams["application_name"] = c.ApplicationName
+ cfg.RuntimeParams["application_name"] = viper.GetString(keys.ApplicationName)
return cfg, nil
}
@@ -455,6 +467,9 @@ func (ps *bunDBService) MentionStringsToMentions(ctx context.Context, targetAcco
}
func (ps *bunDBService) TagStringsToTags(ctx context.Context, tags []string, originAccountID string) ([]*gtsmodel.Tag, error) {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
+
newTags := []*gtsmodel.Tag{}
for _, t := range tags {
tag := &gtsmodel.Tag{}
@@ -468,7 +483,7 @@ func (ps *bunDBService) TagStringsToTags(ctx context.Context, tags []string, ori
return nil, err
}
tag.ID = newID
- tag.URL = fmt.Sprintf("%s://%s/tags/%s", ps.config.Protocol, ps.config.Host, t)
+ tag.URL = fmt.Sprintf("%s://%s/tags/%s", protocol, host, t)
tag.Name = t
tag.FirstSeenFromAccountID = originAccountID
tag.CreatedAt = time.Now()
diff --git a/internal/db/bundb/bundb_test.go b/internal/db/bundb/bundb_test.go
index d4655a253..70fd58422 100644
--- a/internal/db/bundb/bundb_test.go
+++ b/internal/db/bundb/bundb_test.go
@@ -20,7 +20,6 @@ package bundb_test
import (
"github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/testrig"
@@ -29,8 +28,7 @@ import (
type BunDBStandardTestSuite struct {
// standard suite interfaces
suite.Suite
- config *config.Config
- db db.DB
+ db db.DB
// standard suite models
testTokens map[string]*gtsmodel.Token
@@ -57,10 +55,10 @@ func (suite *BunDBStandardTestSuite) SetupSuite() {
}
func (suite *BunDBStandardTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
- suite.db = testrig.NewTestDB()
testrig.InitTestLog()
+ testrig.InitTestConfig()
+ suite.db = testrig.NewTestDB()
testrig.StandardDBSetup(suite.db, suite.testAccounts)
}
diff --git a/internal/db/bundb/domain.go b/internal/db/bundb/domain.go
index 5cb98e87e..9e6aa968d 100644
--- a/internal/db/bundb/domain.go
+++ b/internal/db/bundb/domain.go
@@ -22,15 +22,13 @@ import (
"context"
"net/url"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/util"
)
type domainDB struct {
- config *config.Config
- conn *DBConn
+ conn *DBConn
}
func (d *domainDB) IsDomainBlocked(ctx context.Context, domain string) (bool, db.Error) {
diff --git a/internal/db/bundb/instance.go b/internal/db/bundb/instance.go
index 006a76e24..4c47a96f4 100644
--- a/internal/db/bundb/instance.go
+++ b/internal/db/bundb/instance.go
@@ -20,7 +20,9 @@ package bundb
import (
"context"
+
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
@@ -29,8 +31,7 @@ import (
)
type instanceDB struct {
- config *config.Config
- conn *DBConn
+ conn *DBConn
}
func (i *instanceDB) CountInstanceUsers(ctx context.Context, domain string) (int, db.Error) {
@@ -40,7 +41,8 @@ func (i *instanceDB) CountInstanceUsers(ctx context.Context, domain string) (int
Where("username != ?", domain).
Where("? IS NULL", bun.Ident("suspended_at"))
- if domain == i.config.Host {
+ host := viper.GetString(config.Keys.Host)
+ if domain == host {
// if the domain is *this* domain, just count where the domain field is null
q = q.WhereGroup(" AND ", whereEmptyOrNull("domain"))
} else {
@@ -59,7 +61,8 @@ func (i *instanceDB) CountInstanceStatuses(ctx context.Context, domain string) (
NewSelect().
Model(&[]*gtsmodel.Status{})
- if domain == i.config.Host {
+ host := viper.GetString(config.Keys.Host)
+ if domain == host {
// if the domain is *this* domain, just count where local is true
q = q.Where("local = ?", true)
} else {
@@ -80,7 +83,8 @@ func (i *instanceDB) CountInstanceDomains(ctx context.Context, domain string) (i
NewSelect().
Model(&[]*gtsmodel.Instance{})
- if domain == i.config.Host {
+ host := viper.GetString(config.Keys.Host)
+ if domain == host {
// if the domain is *this* domain, just count other instances it knows about
// exclude domains that are blocked
q = q.
diff --git a/internal/db/bundb/media.go b/internal/db/bundb/media.go
index 1a06a0260..5ea995a2d 100644
--- a/internal/db/bundb/media.go
+++ b/internal/db/bundb/media.go
@@ -21,15 +21,13 @@ package bundb
import (
"context"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/uptrace/bun"
)
type mediaDB struct {
- config *config.Config
- conn *DBConn
+ conn *DBConn
}
func (m *mediaDB) newMediaQ(i interface{}) *bun.SelectQuery {
diff --git a/internal/db/bundb/mention.go b/internal/db/bundb/mention.go
index 81ad216cc..f38b02a22 100644
--- a/internal/db/bundb/mention.go
+++ b/internal/db/bundb/mention.go
@@ -22,16 +22,14 @@ import (
"context"
"github.com/ReneKroon/ttlcache"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/uptrace/bun"
)
type mentionDB struct {
- config *config.Config
- conn *DBConn
- cache *ttlcache.Cache
+ conn *DBConn
+ cache *ttlcache.Cache
}
func (m *mentionDB) newMentionQ(i interface{}) *bun.SelectQuery {
diff --git a/internal/db/bundb/notification.go b/internal/db/bundb/notification.go
index 212c97467..e9203c030 100644
--- a/internal/db/bundb/notification.go
+++ b/internal/db/bundb/notification.go
@@ -22,16 +22,14 @@ import (
"context"
"github.com/ReneKroon/ttlcache"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/uptrace/bun"
)
type notificationDB struct {
- config *config.Config
- conn *DBConn
- cache *ttlcache.Cache
+ conn *DBConn
+ cache *ttlcache.Cache
}
func (n *notificationDB) newNotificationQ(i interface{}) *bun.SelectQuery {
diff --git a/internal/db/bundb/relationship.go b/internal/db/bundb/relationship.go
index a98a9f426..f8d1bccbe 100644
--- a/internal/db/bundb/relationship.go
+++ b/internal/db/bundb/relationship.go
@@ -23,15 +23,13 @@ import (
"database/sql"
"fmt"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/uptrace/bun"
)
type relationshipDB struct {
- config *config.Config
- conn *DBConn
+ conn *DBConn
}
func (r *relationshipDB) newBlockQ(block *gtsmodel.Block) *bun.SelectQuery {
diff --git a/internal/db/bundb/session.go b/internal/db/bundb/session.go
index acc70a868..60e582abd 100644
--- a/internal/db/bundb/session.go
+++ b/internal/db/bundb/session.go
@@ -23,15 +23,13 @@ import (
"crypto/rand"
"errors"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id"
)
type sessionDB struct {
- config *config.Config
- conn *DBConn
+ conn *DBConn
}
func (s *sessionDB) GetSession(ctx context.Context) (*gtsmodel.RouterSession, db.Error) {
diff --git a/internal/db/bundb/status.go b/internal/db/bundb/status.go
index 73e2cb4c0..8c157e77a 100644
--- a/internal/db/bundb/status.go
+++ b/internal/db/bundb/status.go
@@ -25,16 +25,14 @@ import (
"github.com/sirupsen/logrus"
"github.com/superseriousbusiness/gotosocial/internal/cache"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/uptrace/bun"
)
type statusDB struct {
- config *config.Config
- conn *DBConn
- cache *cache.StatusCache
+ conn *DBConn
+ cache *cache.StatusCache
// TODO: keep method definitions in same place but instead have receiver
// all point to one single "db" type, so they can all share methods
diff --git a/internal/db/bundb/timeline.go b/internal/db/bundb/timeline.go
index fb17fc53c..bb81d56cb 100644
--- a/internal/db/bundb/timeline.go
+++ b/internal/db/bundb/timeline.go
@@ -23,15 +23,13 @@ import (
"database/sql"
"sort"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/uptrace/bun"
)
type timelineDB struct {
- config *config.Config
- conn *DBConn
+ conn *DBConn
}
func (t *timelineDB) GetHomeTimeline(ctx context.Context, accountID string, maxID string, sinceID string, minID string, limit int, local bool) ([]*gtsmodel.Status, db.Error) {
diff --git a/internal/email/noopsender.go b/internal/email/noopsender.go
index 82eb8db44..d2c9bbb1b 100644
--- a/internal/email/noopsender.go
+++ b/internal/email/noopsender.go
@@ -23,13 +23,17 @@ import (
"html/template"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
)
// NewNoopSender returns a no-op email sender that will just execute the given sendCallback
// every time it would otherwise send an email to the given toAddress with the given message value.
//
// Passing a nil function is also acceptable, in which case the send functions will just return nil.
-func NewNoopSender(templateBaseDir string, sendCallback func(toAddress string, message string)) (Sender, error) {
+func NewNoopSender(sendCallback func(toAddress string, message string)) (Sender, error) {
+ templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir)
+
t, err := loadTemplates(templateBaseDir)
if err != nil {
return nil, err
diff --git a/internal/email/sender.go b/internal/email/sender.go
index a6a9abe55..546a5e9ce 100644
--- a/internal/email/sender.go
+++ b/internal/email/sender.go
@@ -23,6 +23,7 @@ import (
"html/template"
"net/smtp"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/config"
)
@@ -36,18 +37,25 @@ type Sender interface {
}
// NewSender returns a new email Sender interface with the given configuration, or an error if something goes wrong.
-func NewSender(cfg *config.Config) (Sender, error) {
- t, err := loadTemplates(cfg.TemplateConfig.BaseDir)
+func NewSender() (Sender, error) {
+ keys := config.Keys
+
+ templateBaseDir := viper.GetString(keys.WebTemplateBaseDir)
+ t, err := loadTemplates(templateBaseDir)
if err != nil {
return nil, err
}
- auth := smtp.PlainAuth("", cfg.SMTPConfig.Username, cfg.SMTPConfig.Password, cfg.SMTPConfig.Host)
+ username := viper.GetString(keys.SMTPUsername)
+ password := viper.GetString(keys.SMTPPassword)
+ host := viper.GetString(keys.SMTPHost)
+ port := viper.GetInt(keys.SMTPPort)
+ from := viper.GetString(keys.SMTPFrom)
return &sender{
- hostAddress: fmt.Sprintf("%s:%d", cfg.SMTPConfig.Host, cfg.SMTPConfig.Port),
- from: cfg.SMTPConfig.From,
- auth: auth,
+ hostAddress: fmt.Sprintf("%s:%d", host, port),
+ from: from,
+ auth: smtp.PlainAuth("", username, password, host),
template: t,
}, nil
}
diff --git a/internal/federation/authenticate.go b/internal/federation/authenticate.go
index fea5a765a..9d715c549 100644
--- a/internal/federation/authenticate.go
+++ b/internal/federation/authenticate.go
@@ -29,11 +29,13 @@ import (
"strings"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/go-fed/httpsig"
"github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/activity/streams"
"github.com/superseriousbusiness/activity/streams/vocab"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/util"
@@ -155,7 +157,8 @@ func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedU
requestingRemoteAccount := &gtsmodel.Account{}
requestingLocalAccount := &gtsmodel.Account{}
requestingHost := requestingPublicKeyID.Host
- if strings.EqualFold(requestingHost, f.config.Host) {
+ host := viper.GetString(config.Keys.Host)
+ if strings.EqualFold(requestingHost, host) {
// LOCAL ACCOUNT REQUEST
// the request is coming from INSIDE THE HOUSE so skip the remote dereferencing
l.Tracef("proceeding without dereference for local public key %s", requestingPublicKeyID)
diff --git a/internal/federation/dereferencing/dereferencer.go b/internal/federation/dereferencing/dereferencer.go
index 76fd830a2..c105665f3 100644
--- a/internal/federation/dereferencing/dereferencer.go
+++ b/internal/federation/dereferencing/dereferencer.go
@@ -24,7 +24,6 @@ import (
"sync"
"github.com/superseriousbusiness/gotosocial/internal/ap"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/media"
@@ -82,19 +81,17 @@ type deref struct {
typeConverter typeutils.TypeConverter
transportController transport.Controller
mediaHandler media.Handler
- config *config.Config
handshakes map[string][]*url.URL
handshakeSync *sync.Mutex // mutex to lock/unlock when checking or updating the handshakes map
}
// NewDereferencer returns a Dereferencer initialized with the given parameters.
-func NewDereferencer(config *config.Config, db db.DB, typeConverter typeutils.TypeConverter, transportController transport.Controller, mediaHandler media.Handler) Dereferencer {
+func NewDereferencer(db db.DB, typeConverter typeutils.TypeConverter, transportController transport.Controller, mediaHandler media.Handler) Dereferencer {
return &deref{
db: db,
typeConverter: typeConverter,
transportController: transportController,
mediaHandler: mediaHandler,
- config: config,
handshakeSync: &sync.Mutex{},
}
}
diff --git a/internal/federation/dereferencing/dereferencer_test.go b/internal/federation/dereferencing/dereferencer_test.go
index d4bf3396d..8bcee8615 100644
--- a/internal/federation/dereferencing/dereferencer_test.go
+++ b/internal/federation/dereferencing/dereferencer_test.go
@@ -29,7 +29,6 @@ import (
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/activity/streams"
"github.com/superseriousbusiness/activity/streams/vocab"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -39,7 +38,6 @@ import (
type DereferencerStandardTestSuite struct {
suite.Suite
- config *config.Config
db db.DB
storage *kv.KVStore
@@ -61,11 +59,12 @@ func (suite *DereferencerStandardTestSuite) SetupSuite() {
}
func (suite *DereferencerStandardTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
- suite.db = testrig.NewTestDB()
testrig.InitTestLog()
+ testrig.InitTestConfig()
+
+ suite.db = testrig.NewTestDB()
suite.storage = testrig.NewTestStorage()
- suite.dereferencer = dereferencing.NewDereferencer(suite.config, suite.db, testrig.NewTestTypeConverter(suite.db), suite.mockTransportController(), testrig.NewTestMediaHandler(suite.db, suite.storage))
+ suite.dereferencer = dereferencing.NewDereferencer(suite.db, testrig.NewTestTypeConverter(suite.db), suite.mockTransportController(), testrig.NewTestMediaHandler(suite.db, suite.storage))
testrig.StandardDBSetup(suite.db, nil)
}
diff --git a/internal/federation/dereferencing/thread.go b/internal/federation/dereferencing/thread.go
index db1d336c6..209df32c4 100644
--- a/internal/federation/dereferencing/thread.go
+++ b/internal/federation/dereferencing/thread.go
@@ -24,7 +24,9 @@ import (
"net/url"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/ap"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/util"
)
@@ -43,7 +45,8 @@ func (d *deref) DereferenceThread(ctx context.Context, username string, statusIR
l.Debug("entering DereferenceThread")
// if it's our status we already have everything stashed so we can bail early
- if statusIRI.Host == d.config.Host {
+ host := viper.GetString(config.Keys.Host)
+ if statusIRI.Host == host {
l.Debug("iri belongs to us, bailing")
return nil
}
@@ -77,7 +80,8 @@ func (d *deref) iterateAncestors(ctx context.Context, username string, statusIRI
l.Debug("entering iterateAncestors")
// if it's our status we don't need to dereference anything so we can immediately move up the chain
- if statusIRI.Host == d.config.Host {
+ host := viper.GetString(config.Keys.Host)
+ if statusIRI.Host == host {
l.Debug("iri belongs to us, moving up to next ancestor")
// since this is our status, we know we can extract the id from the status path
@@ -129,7 +133,8 @@ func (d *deref) iterateDescendants(ctx context.Context, username string, statusI
l.Debug("entering iterateDescendants")
// if it's our status we already have descendants stashed so we can bail early
- if statusIRI.Host == d.config.Host {
+ host := viper.GetString(config.Keys.Host)
+ if statusIRI.Host == host {
l.Debug("iri belongs to us, bailing")
return nil
}
@@ -205,7 +210,8 @@ pageLoop:
continue
}
- if itemURI.Host == d.config.Host {
+ host := viper.GetString(config.Keys.Host)
+ if itemURI.Host == host {
// skip if the reply is from us -- we already have it then
continue
}
diff --git a/internal/federation/federatingdb/db.go b/internal/federation/federatingdb/db.go
index 4b2f92fd4..64e5ad359 100644
--- a/internal/federation/federatingdb/db.go
+++ b/internal/federation/federatingdb/db.go
@@ -25,7 +25,6 @@ import (
"github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/activity/streams/vocab"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
)
@@ -46,19 +45,17 @@ type federatingDB struct {
locks map[string]*mutex
pool sync.Pool
db db.DB
- config *config.Config
typeConverter typeutils.TypeConverter
}
// New returns a DB interface using the given database and config
-func New(db db.DB, config *config.Config) DB {
+func New(db db.DB) DB {
fdb := federatingDB{
mutex: sync.Mutex{},
locks: make(map[string]*mutex, 100),
pool: sync.Pool{New: func() interface{} { return &mutex{} }},
db: db,
- config: config,
- typeConverter: typeutils.NewConverter(config, db),
+ typeConverter: typeutils.NewConverter(db),
}
go fdb.cleanupLocks()
return &fdb
diff --git a/internal/federation/federatingdb/federatingdb_test.go b/internal/federation/federatingdb/federatingdb_test.go
index 24cbfed98..d51e0a825 100644
--- a/internal/federation/federatingdb/federatingdb_test.go
+++ b/internal/federation/federatingdb/federatingdb_test.go
@@ -22,7 +22,6 @@ import (
"context"
"github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -34,7 +33,6 @@ import (
type FederatingDBTestSuite struct {
suite.Suite
- config *config.Config
db db.DB
tc typeutils.TypeConverter
federatingDB federatingdb.DB
@@ -59,13 +57,13 @@ func (suite *FederatingDBTestSuite) SetupSuite() {
suite.testAttachments = testrig.NewTestAttachments()
suite.testStatuses = testrig.NewTestStatuses()
suite.testBlocks = testrig.NewTestBlocks()
- suite.testActivities = testrig.NewTestActivities(suite.testAccounts)
}
func (suite *FederatingDBTestSuite) SetupTest() {
testrig.InitTestLog()
- suite.config = testrig.NewTestConfig()
+ testrig.InitTestConfig()
suite.db = testrig.NewTestDB()
+ suite.testActivities = testrig.NewTestActivities(suite.testAccounts)
suite.tc = testrig.NewTestTypeConverter(suite.db)
suite.federatingDB = testrig.NewTestFederatingDB(suite.db)
testrig.StandardDBSetup(suite.db, suite.testAccounts)
diff --git a/internal/federation/federatingdb/owns.go b/internal/federation/federatingdb/owns.go
index 8846c52bb..2603c9aa2 100644
--- a/internal/federation/federatingdb/owns.go
+++ b/internal/federation/federatingdb/owns.go
@@ -24,6 +24,8 @@ import (
"net/url"
"github.com/sirupsen/logrus"
+ "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/util"
@@ -42,8 +44,9 @@ func (f *federatingDB) Owns(ctx context.Context, id *url.URL) (bool, error) {
l.Debug("entering Owns")
// if the id host isn't this instance host, we don't own this IRI
- if id.Host != f.config.Host {
- l.Tracef("we DO NOT own activity because the host is %s not %s", id.Host, f.config.Host)
+ host := viper.GetString(config.Keys.Host)
+ if id.Host != host {
+ l.Tracef("we DO NOT own activity because the host is %s not %s", id.Host, host)
return false, nil
}
diff --git a/internal/federation/federatingdb/reject_test.go b/internal/federation/federatingdb/reject_test.go
index 2b213a3f0..9930d83d2 100644
--- a/internal/federation/federatingdb/reject_test.go
+++ b/internal/federation/federatingdb/reject_test.go
@@ -48,7 +48,7 @@ func (suite *RejectTestSuite) TestRejectFollowRequest() {
ID: "01FJ1S8DX3STJJ6CEYPMZ1M0R3",
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
- URI: util.GenerateURIForFollow(followingAccount.Username, "http", "localhost:8080", "01FJ1S8DX3STJJ6CEYPMZ1M0R3"),
+ URI: util.GenerateURIForFollow(followingAccount.Username, "01FJ1S8DX3STJJ6CEYPMZ1M0R3"),
AccountID: followingAccount.ID,
TargetAccountID: followedAccount.ID,
}
diff --git a/internal/federation/federatingdb/update.go b/internal/federation/federatingdb/update.go
index 8f318ce71..1d56b931f 100644
--- a/internal/federation/federatingdb/update.go
+++ b/internal/federation/federatingdb/update.go
@@ -24,8 +24,10 @@ import (
"fmt"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/activity/streams/vocab"
"github.com/superseriousbusiness/gotosocial/internal/ap"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/util"
@@ -124,7 +126,8 @@ func (f *federatingDB) Update(ctx context.Context, asType vocab.Type) error {
return fmt.Errorf("UPDATE: error converting to account: %s", err)
}
- if updatedAcct.Domain == f.config.Host {
+ host := viper.GetString(config.Keys.Host)
+ if updatedAcct.Domain == host {
// no need to update local accounts
// in fact, if we do this will break the shit out of things so do NOT
return nil
diff --git a/internal/federation/federatingdb/util.go b/internal/federation/federatingdb/util.go
index f35fbbb2d..afa09e39d 100644
--- a/internal/federation/federatingdb/util.go
+++ b/internal/federation/federatingdb/util.go
@@ -26,9 +26,11 @@ import (
"net/url"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/activity/streams"
"github.com/superseriousbusiness/activity/streams/vocab"
"github.com/superseriousbusiness/gotosocial/internal/ap"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id"
@@ -104,7 +106,7 @@ func (f *federatingDB) NewID(ctx context.Context, t vocab.Type) (idURL *url.URL,
if err != nil {
return nil, err
}
- return url.Parse(util.GenerateURIForFollow(actorAccount.Username, f.config.Protocol, f.config.Host, newID))
+ return url.Parse(util.GenerateURIForFollow(actorAccount.Username, newID))
}
}
}
@@ -207,7 +209,10 @@ func (f *federatingDB) NewID(ctx context.Context, t vocab.Type) (idURL *url.URL,
if err != nil {
return nil, err
}
- return url.Parse(fmt.Sprintf("%s://%s/%s", f.config.Protocol, f.config.Host, newID))
+
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
+ return url.Parse(fmt.Sprintf("%s://%s/%s", protocol, host, newID))
}
// ActorForOutbox fetches the actor's IRI for the given outbox IRI.
diff --git a/internal/federation/federator.go b/internal/federation/federator.go
index 280375d7d..8ccae9427 100644
--- a/internal/federation/federator.go
+++ b/internal/federation/federator.go
@@ -24,7 +24,6 @@ import (
"github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/gotosocial/internal/ap"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation/dereferencing"
"github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb"
@@ -73,7 +72,6 @@ type Federator interface {
}
type federator struct {
- config *config.Config
db db.DB
federatingDB federatingdb.DB
clock pub.Clock
@@ -85,12 +83,11 @@ type federator struct {
}
// NewFederator returns a new federator
-func NewFederator(db db.DB, federatingDB federatingdb.DB, transportController transport.Controller, config *config.Config, typeConverter typeutils.TypeConverter, mediaHandler media.Handler) Federator {
- dereferencer := dereferencing.NewDereferencer(config, db, typeConverter, transportController, mediaHandler)
+func NewFederator(db db.DB, federatingDB federatingdb.DB, transportController transport.Controller, typeConverter typeutils.TypeConverter, mediaHandler media.Handler) Federator {
+ dereferencer := dereferencing.NewDereferencer(db, typeConverter, transportController, mediaHandler)
clock := &Clock{}
f := &federator{
- config: config,
db: db,
federatingDB: federatingDB,
clock: &Clock{},
diff --git a/internal/federation/federator_test.go b/internal/federation/federator_test.go
index 7ac149c0d..f907ac00b 100644
--- a/internal/federation/federator_test.go
+++ b/internal/federation/federator_test.go
@@ -30,7 +30,6 @@ import (
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/activity/pub"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -41,7 +40,6 @@ import (
type ProtocolTestSuite struct {
suite.Suite
- config *config.Config
db db.DB
storage *kv.KVStore
typeConverter typeutils.TypeConverter
@@ -52,16 +50,16 @@ type ProtocolTestSuite struct {
// SetupSuite sets some variables on the suite that we can use as consts (more or less) throughout
func (suite *ProtocolTestSuite) SetupSuite() {
// setup standard items
- suite.config = testrig.NewTestConfig()
- suite.db = testrig.NewTestDB()
- testrig.InitTestLog()
suite.storage = testrig.NewTestStorage()
suite.typeConverter = testrig.NewTestTypeConverter(suite.db)
suite.accounts = testrig.NewTestAccounts()
- suite.activities = testrig.NewTestActivities(suite.accounts)
}
func (suite *ProtocolTestSuite) SetupTest() {
+ testrig.InitTestLog()
+ testrig.InitTestConfig()
+ suite.db = testrig.NewTestDB()
+ suite.activities = testrig.NewTestActivities(suite.accounts)
testrig.StandardDBSetup(suite.db, suite.accounts)
}
@@ -80,7 +78,7 @@ func (suite *ProtocolTestSuite) TestPostInboxRequestBodyHook() {
return nil, nil
}), suite.db)
// setup module being tested
- federator := federation.NewFederator(suite.db, testrig.NewTestFederatingDB(suite.db), tc, suite.config, suite.typeConverter, testrig.NewTestMediaHandler(suite.db, suite.storage))
+ federator := federation.NewFederator(suite.db, testrig.NewTestFederatingDB(suite.db), tc, suite.typeConverter, testrig.NewTestMediaHandler(suite.db, suite.storage))
// setup request
ctx := context.Background()
@@ -109,7 +107,7 @@ func (suite *ProtocolTestSuite) TestAuthenticatePostInbox() {
tc := testrig.NewTestTransportController(testrig.NewMockHTTPClient(nil), suite.db)
// now setup module being tested, with the mock transport controller
- federator := federation.NewFederator(suite.db, testrig.NewTestFederatingDB(suite.db), tc, suite.config, suite.typeConverter, testrig.NewTestMediaHandler(suite.db, suite.storage))
+ federator := federation.NewFederator(suite.db, testrig.NewTestFederatingDB(suite.db), tc, suite.typeConverter, testrig.NewTestMediaHandler(suite.db, suite.storage))
request := httptest.NewRequest(http.MethodPost, "http://localhost:8080/users/the_mighty_zork/inbox", nil)
// we need these headers for the request to be validated
diff --git a/internal/gotosocial/gotosocial.go b/internal/gotosocial/gotosocial.go
index e998c16f9..f32b6ad89 100644
--- a/internal/gotosocial/gotosocial.go
+++ b/internal/gotosocial/gotosocial.go
@@ -21,7 +21,6 @@ package gotosocial
import (
"context"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation"
"github.com/superseriousbusiness/gotosocial/internal/router"
@@ -42,12 +41,11 @@ type Server interface {
// NewServer returns a new gotosocial server, initialized with the given configuration.
// An error will be returned the caller if something goes wrong during initialization
// eg., no db or storage connection, port for router already in use, etc.
-func NewServer(db db.DB, apiRouter router.Router, federator federation.Federator, config *config.Config) (Server, error) {
+func NewServer(db db.DB, apiRouter router.Router, federator federation.Federator) (Server, error) {
return &gotosocial{
db: db,
apiRouter: apiRouter,
federator: federator,
- config: config,
}, nil
}
@@ -56,7 +54,6 @@ type gotosocial struct {
db db.DB
apiRouter router.Router
federator federation.Federator
- config *config.Config
}
// Start starts up the gotosocial server. If something goes wrong
diff --git a/internal/media/handler.go b/internal/media/handler.go
index b1063f9aa..24963e404 100644
--- a/internal/media/handler.go
+++ b/internal/media/handler.go
@@ -28,6 +28,7 @@ import (
"codeberg.org/gruf/go-store/kv"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -84,15 +85,13 @@ type Handler interface {
}
type mediaHandler struct {
- config *config.Config
db db.DB
storage *kv.KVStore
}
-// New returns a new handler with the given config, db, and storage
-func New(config *config.Config, database db.DB, storage *kv.KVStore) Handler {
+// New returns a new handler with the given db and storage
+func New(database db.DB, storage *kv.KVStore) Handler {
return &mediaHandler{
- config: config,
db: database,
storage: storage,
}
@@ -179,6 +178,8 @@ func (mh *mediaHandler) ProcessAttachment(ctx context.Context, attachmentBytes [
// *gts.Emoji for it, then returns it to the caller. It's the caller's responsibility to put the returned struct
// in the database.
func (mh *mediaHandler) ProcessLocalEmoji(ctx context.Context, emojiBytes []byte, shortcode string) (*gtsmodel.Emoji, error) {
+ keys := config.Keys
+
var clean []byte
var err error
var original *imageAndMeta
@@ -234,7 +235,10 @@ func (mh *mediaHandler) ProcessLocalEmoji(ctx context.Context, emojiBytes []byte
extension := strings.Split(contentType, "/")[1]
// create the urls and storage paths
- URLbase := fmt.Sprintf("%s://%s%s", mh.config.StorageConfig.ServeProtocol, mh.config.StorageConfig.ServeHost, mh.config.StorageConfig.ServeBasePath)
+ serveProtocol := viper.GetString(keys.StorageServeProtocol)
+ serveHost := viper.GetString(keys.StorageServeHost)
+ serveBasePath := viper.GetString(keys.StorageServeBasePath)
+ URLbase := fmt.Sprintf("%s://%s%s", serveProtocol, serveHost, serveBasePath)
// generate a id for the new emoji
newEmojiID, err := id.NewRandomULID()
@@ -244,7 +248,9 @@ func (mh *mediaHandler) ProcessLocalEmoji(ctx context.Context, emojiBytes []byte
// webfinger uri for the emoji -- unrelated to actually serving the image
// will be something like https://example.org/emoji/70a7f3d7-7e35-4098-8ce3-9b5e8203bb9c
- emojiURI := fmt.Sprintf("%s://%s/%s/%s", mh.config.Protocol, mh.config.Host, Emoji, newEmojiID)
+ protocol := viper.GetString(keys.Protocol)
+ host := viper.GetString(keys.Host)
+ emojiURI := fmt.Sprintf("%s://%s/%s/%s", protocol, host, Emoji, newEmojiID)
// serve url and storage path for the original emoji -- can be png or gif
emojiURL := fmt.Sprintf("%s/%s/%s/%s/%s.%s", URLbase, instanceAccount.ID, Emoji, Original, newEmojiID, extension)
diff --git a/internal/media/processicon.go b/internal/media/processicon.go
index 46c721e0c..5f4f8b138 100644
--- a/internal/media/processicon.go
+++ b/internal/media/processicon.go
@@ -24,6 +24,8 @@ import (
"strings"
"time"
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id"
)
@@ -79,7 +81,12 @@ func (mh *mediaHandler) processHeaderOrAvi(imageBytes []byte, contentType string
return nil, err
}
- URLbase := fmt.Sprintf("%s://%s%s", mh.config.StorageConfig.ServeProtocol, mh.config.StorageConfig.ServeHost, mh.config.StorageConfig.ServeBasePath)
+ keys := config.Keys
+ serveProtocol := viper.GetString(keys.StorageServeProtocol)
+ serveHost := viper.GetString(keys.StorageServeHost)
+ serveBasePath := viper.GetString(keys.StorageServeBasePath)
+
+ URLbase := fmt.Sprintf("%s://%s%s", serveProtocol, serveHost, serveBasePath)
originalURL := fmt.Sprintf("%s/%s/%s/original/%s.%s", URLbase, accountID, mediaType, newMediaID, extension)
smallURL := fmt.Sprintf("%s/%s/%s/small/%s.%s", URLbase, accountID, mediaType, newMediaID, extension)
diff --git a/internal/media/processimage.go b/internal/media/processimage.go
index 03bd4eda8..f3b520ad9 100644
--- a/internal/media/processimage.go
+++ b/internal/media/processimage.go
@@ -24,6 +24,8 @@ import (
"strings"
"time"
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/id"
)
@@ -67,7 +69,12 @@ func (mh *mediaHandler) processImageAttachment(data []byte, minAttachment *gtsmo
return nil, err
}
- URLbase := fmt.Sprintf("%s://%s%s", mh.config.StorageConfig.ServeProtocol, mh.config.StorageConfig.ServeHost, mh.config.StorageConfig.ServeBasePath)
+ keys := config.Keys
+ serveProtocol := viper.GetString(keys.StorageServeProtocol)
+ serveHost := viper.GetString(keys.StorageServeHost)
+ serveBasePath := viper.GetString(keys.StorageServeBasePath)
+
+ URLbase := fmt.Sprintf("%s://%s%s", serveProtocol, serveHost, serveBasePath)
originalURL := fmt.Sprintf("%s/%s/attachment/original/%s.%s", URLbase, minAttachment.AccountID, newMediaID, extension)
smallURL := fmt.Sprintf("%s/%s/attachment/small/%s.jpeg", URLbase, minAttachment.AccountID, newMediaID) // all thumbnails/smalls are encoded as jpeg
diff --git a/internal/oauth/clientstore_test.go b/internal/oauth/clientstore_test.go
index b0a36487b..fc74f3ad1 100644
--- a/internal/oauth/clientstore_test.go
+++ b/internal/oauth/clientstore_test.go
@@ -49,6 +49,8 @@ func (suite *PgClientStoreTestSuite) SetupSuite() {
// SetupTest creates a postgres connection and creates the oauth_clients table before each test
func (suite *PgClientStoreTestSuite) SetupTest() {
+ testrig.InitTestLog()
+ testrig.InitTestConfig()
suite.db = testrig.NewTestDB()
testrig.StandardDBSetup(suite.db, nil)
}
diff --git a/internal/oidc/idp.go b/internal/oidc/idp.go
index 3032d15d5..166fc4b85 100644
--- a/internal/oidc/idp.go
+++ b/internal/oidc/idp.go
@@ -23,6 +23,7 @@ import (
"fmt"
"github.com/coreos/go-oidc/v3/oidc"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/config"
"golang.org/x/oauth2"
)
@@ -54,42 +55,56 @@ type idp struct {
// If the passed config contains a nil value for the OIDCConfig, or OIDCConfig.Enabled
// is set to false, then nil, nil will be returned. If OIDCConfig.Enabled is true,
// then the other OIDC config fields must also be set.
-func NewIDP(ctx context.Context, config *config.Config) (IDP, error) {
+func NewIDP(ctx context.Context) (IDP, error) {
+ keys := config.Keys
- // oidc isn't enabled so we don't need to do anything
- if config.OIDCConfig == nil || !config.OIDCConfig.Enabled {
+ oidcEnabled := viper.GetBool(keys.OIDCEnabled)
+ if !oidcEnabled {
+ // oidc isn't enabled so we don't need to do anything
return nil, nil
}
// validate config fields
- if config.OIDCConfig.IDPName == "" {
+ idpName := viper.GetString(keys.OIDCIdpName)
+ if idpName == "" {
return nil, fmt.Errorf("not set: IDPName")
}
- if config.OIDCConfig.Issuer == "" {
+
+ issuer := viper.GetString(keys.OIDCIssuer)
+ if issuer == "" {
return nil, fmt.Errorf("not set: Issuer")
}
- if config.OIDCConfig.ClientID == "" {
+
+ clientID := viper.GetString(keys.OIDCClientID)
+ if clientID == "" {
return nil, fmt.Errorf("not set: ClientID")
}
- if config.OIDCConfig.ClientSecret == "" {
+
+ clientSecret := viper.GetString(keys.OIDCClientSecret)
+ if clientSecret == "" {
return nil, fmt.Errorf("not set: ClientSecret")
}
- if len(config.OIDCConfig.Scopes) == 0 {
+
+ scopes := viper.GetStringSlice(keys.OIDCScopes)
+ if len(scopes) == 0 {
return nil, fmt.Errorf("not set: Scopes")
}
- provider, err := oidc.NewProvider(ctx, config.OIDCConfig.Issuer)
+ provider, err := oidc.NewProvider(ctx, issuer)
if err != nil {
return nil, err
}
+ protocol := viper.GetString(keys.Protocol)
+ host := viper.GetString(keys.Host)
+
oauth2Config := oauth2.Config{
// client_id and client_secret of the client.
- ClientID: config.OIDCConfig.ClientID,
- ClientSecret: config.OIDCConfig.ClientSecret,
+ ClientID: clientID,
+ ClientSecret: clientSecret,
// The redirectURL.
- RedirectURL: fmt.Sprintf("%s://%s%s", config.Protocol, config.Host, CallbackPath),
+ RedirectURL: fmt.Sprintf("%s://%s%s", protocol, host, CallbackPath),
// Discovery returns the OAuth2 endpoints.
Endpoint: provider.Endpoint(),
@@ -97,14 +112,16 @@ func NewIDP(ctx context.Context, config *config.Config) (IDP, error) {
// "openid" is a required scope for OpenID Connect flows.
//
// Other scopes, such as "groups" can be requested.
- Scopes: config.OIDCConfig.Scopes,
+ Scopes: scopes,
}
// create a config for verifier creation
oidcConf := &oidc.Config{
- ClientID: config.OIDCConfig.ClientID,
+ ClientID: clientID,
}
- if config.OIDCConfig.SkipVerification {
+
+ skipVerification := viper.GetBool(keys.OIDCSkipVerification)
+ if skipVerification {
oidcConf.SkipClientIDCheck = true
oidcConf.SkipExpiryCheck = true
oidcConf.SkipIssuerCheck = true
diff --git a/internal/processing/account/account.go b/internal/processing/account/account.go
index 4e807540c..c37261adc 100644
--- a/internal/processing/account/account.go
+++ b/internal/processing/account/account.go
@@ -23,7 +23,6 @@ import (
"mime/multipart"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
@@ -78,7 +77,6 @@ type Processor interface {
type processor struct {
tc typeutils.TypeConverter
- config *config.Config
mediaHandler media.Handler
fromClientAPI chan messages.FromClientAPI
oauthServer oauth.Server
@@ -89,15 +87,14 @@ type processor struct {
}
// New returns a new account processor.
-func New(db db.DB, tc typeutils.TypeConverter, mediaHandler media.Handler, oauthServer oauth.Server, fromClientAPI chan messages.FromClientAPI, federator federation.Federator, config *config.Config) Processor {
+func New(db db.DB, tc typeutils.TypeConverter, mediaHandler media.Handler, oauthServer oauth.Server, fromClientAPI chan messages.FromClientAPI, federator federation.Federator) Processor {
return &processor{
tc: tc,
- config: config,
mediaHandler: mediaHandler,
fromClientAPI: fromClientAPI,
oauthServer: oauthServer,
filter: visibility.NewFilter(db),
- formatter: text.NewFormatter(config, db),
+ formatter: text.NewFormatter(db),
db: db,
federator: federator,
}
diff --git a/internal/processing/account/account_test.go b/internal/processing/account/account_test.go
index 9bc97a77b..17893b4c0 100644
--- a/internal/processing/account/account_test.go
+++ b/internal/processing/account/account_test.go
@@ -22,7 +22,6 @@ import (
"codeberg.org/gruf/go-store/kv"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/activity/pub"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/email"
"github.com/superseriousbusiness/gotosocial/internal/federation"
@@ -39,7 +38,6 @@ import (
type AccountStandardTestSuite struct {
// standard suite interfaces
suite.Suite
- config *config.Config
db db.DB
tc typeutils.TypeConverter
storage *kv.KVStore
@@ -76,9 +74,10 @@ func (suite *AccountStandardTestSuite) SetupSuite() {
}
func (suite *AccountStandardTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
- suite.db = testrig.NewTestDB()
testrig.InitTestLog()
+ testrig.InitTestConfig()
+
+ suite.db = testrig.NewTestDB()
suite.tc = testrig.NewTestTypeConverter(suite.db)
suite.storage = testrig.NewTestStorage()
suite.mediaHandler = testrig.NewTestMediaHandler(suite.db, suite.storage)
@@ -89,7 +88,7 @@ func (suite *AccountStandardTestSuite) SetupTest() {
suite.federator = testrig.NewTestFederator(suite.db, suite.transportController, suite.storage)
suite.sentEmails = make(map[string]string)
suite.emailSender = testrig.NewEmailSender("../../../web/template/", suite.sentEmails)
- suite.accountProcessor = account.New(suite.db, suite.tc, suite.mediaHandler, suite.oauthServer, suite.fromClientAPIChan, suite.federator, suite.config)
+ suite.accountProcessor = account.New(suite.db, suite.tc, suite.mediaHandler, suite.oauthServer, suite.fromClientAPIChan, suite.federator)
testrig.StandardDBSetup(suite.db, nil)
testrig.StandardStorageSetup(suite.storage, "../../../testrig/media")
}
diff --git a/internal/processing/account/create.go b/internal/processing/account/create.go
index a13e84a78..3d024417b 100644
--- a/internal/processing/account/create.go
+++ b/internal/processing/account/create.go
@@ -23,9 +23,11 @@ import (
"fmt"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/ap"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/text"
@@ -51,14 +53,18 @@ func (p *processor) Create(ctx context.Context, applicationToken oauth2.TokenInf
return nil, fmt.Errorf("username %s in use", form.Username)
}
+ keys := config.Keys
+ reasonRequired := viper.GetBool(keys.AccountsReasonRequired)
+ approvalRequired := viper.GetBool(keys.AccountsApprovalRequired)
+
// don't store a reason if we don't require one
reason := form.Reason
- if !p.config.AccountsConfig.ReasonRequired {
+ if !reasonRequired {
reason = ""
}
l.Trace("creating new username and account")
- user, err := p.db.NewSignup(ctx, form.Username, text.RemoveHTML(reason), p.config.AccountsConfig.RequireApproval, form.Email, form.Password, form.IP, form.Locale, application.ID, false, false)
+ user, err := p.db.NewSignup(ctx, form.Username, text.RemoveHTML(reason), approvalRequired, form.Email, form.Password, form.IP, form.Locale, application.ID, false, false)
if err != nil {
return nil, fmt.Errorf("error creating new signup in the database: %s", err)
}
diff --git a/internal/processing/account/createblock.go b/internal/processing/account/createblock.go
index 347f19bee..6785ffed1 100644
--- a/internal/processing/account/createblock.go
+++ b/internal/processing/account/createblock.go
@@ -57,7 +57,7 @@ func (p *processor) BlockCreate(ctx context.Context, requestingAccount *gtsmodel
block.Account = requestingAccount
block.TargetAccountID = targetAccountID
block.TargetAccount = targetAccount
- block.URI = util.GenerateURIForBlock(requestingAccount.Username, p.config.Protocol, p.config.Host, newBlockID)
+ block.URI = util.GenerateURIForBlock(requestingAccount.Username, newBlockID)
// whack it in the database
if err := p.db.Put(ctx, block); err != nil {
diff --git a/internal/processing/account/createfollow.go b/internal/processing/account/createfollow.go
index d3ca386ed..9b082187b 100644
--- a/internal/processing/account/createfollow.go
+++ b/internal/processing/account/createfollow.go
@@ -76,7 +76,7 @@ func (p *processor) FollowCreate(ctx context.Context, requestingAccount *gtsmode
AccountID: requestingAccount.ID,
TargetAccountID: form.ID,
ShowReblogs: true,
- URI: util.GenerateURIForFollow(requestingAccount.Username, p.config.Protocol, p.config.Host, newFollowID),
+ URI: util.GenerateURIForFollow(requestingAccount.Username, newFollowID),
Notify: false,
}
if form.Reblogs != nil {
diff --git a/internal/processing/account/update.go b/internal/processing/account/update.go
index 54bf372e7..ca386eb39 100644
--- a/internal/processing/account/update.go
+++ b/internal/processing/account/update.go
@@ -23,12 +23,15 @@ import (
"context"
"errors"
"fmt"
- "github.com/sirupsen/logrus"
"io"
"mime/multipart"
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
+
"github.com/superseriousbusiness/gotosocial/internal/ap"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/media"
"github.com/superseriousbusiness/gotosocial/internal/messages"
@@ -135,8 +138,9 @@ func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, form
// the account's new avatar image.
func (p *processor) UpdateAvatar(ctx context.Context, avatar *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) {
var err error
- if int(avatar.Size) > p.config.MediaConfig.MaxImageSize {
- err = fmt.Errorf("avatar with size %d exceeded max image size of %d bytes", avatar.Size, p.config.MediaConfig.MaxImageSize)
+ maxImageSize := viper.GetInt(config.Keys.MediaImageMaxSize)
+ if int(avatar.Size) > maxImageSize {
+ err = fmt.Errorf("avatar with size %d exceeded max image size of %d bytes", avatar.Size, maxImageSize)
return nil, err
}
f, err := avatar.Open()
@@ -168,8 +172,9 @@ func (p *processor) UpdateAvatar(ctx context.Context, avatar *multipart.FileHead
// the account's new header image.
func (p *processor) UpdateHeader(ctx context.Context, header *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) {
var err error
- if int(header.Size) > p.config.MediaConfig.MaxImageSize {
- err = fmt.Errorf("header with size %d exceeded max image size of %d bytes", header.Size, p.config.MediaConfig.MaxImageSize)
+ maxImageSize := viper.GetInt(config.Keys.MediaImageMaxSize)
+ if int(header.Size) > maxImageSize {
+ err = fmt.Errorf("header with size %d exceeded max image size of %d bytes", header.Size, maxImageSize)
return nil, err
}
f, err := header.Open()
diff --git a/internal/processing/admin/admin.go b/internal/processing/admin/admin.go
index 1aaaced5e..8b46ab6b7 100644
--- a/internal/processing/admin/admin.go
+++ b/internal/processing/admin/admin.go
@@ -23,7 +23,6 @@ import (
"mime/multipart"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -44,17 +43,15 @@ type Processor interface {
type processor struct {
tc typeutils.TypeConverter
- config *config.Config
mediaHandler media.Handler
fromClientAPI chan messages.FromClientAPI
db db.DB
}
// New returns a new admin processor.
-func New(db db.DB, tc typeutils.TypeConverter, mediaHandler media.Handler, fromClientAPI chan messages.FromClientAPI, config *config.Config) Processor {
+func New(db db.DB, tc typeutils.TypeConverter, mediaHandler media.Handler, fromClientAPI chan messages.FromClientAPI) Processor {
return &processor{
tc: tc,
- config: config,
mediaHandler: mediaHandler,
fromClientAPI: fromClientAPI,
db: db,
diff --git a/internal/processing/blocks.go b/internal/processing/blocks.go
index 1144579a4..ad5553be9 100644
--- a/internal/processing/blocks.go
+++ b/internal/processing/blocks.go
@@ -23,7 +23,9 @@ import (
"fmt"
"net/url"
+ "github.com/spf13/viper"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
@@ -62,17 +64,20 @@ func (p *processor) packageBlocksResponse(accounts []*apimodel.Account, path str
// prepare the next and previous links
if len(accounts) != 0 {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
+
nextLink := &url.URL{
- Scheme: p.config.Protocol,
- Host: p.config.Host,
+ Scheme: protocol,
+ Host: host,
Path: path,
RawQuery: fmt.Sprintf("limit=%d&max_id=%s", limit, nextMaxID),
}
next := fmt.Sprintf("<%s>; rel=\"next\"", nextLink.String())
prevLink := &url.URL{
- Scheme: p.config.Protocol,
- Host: p.config.Host,
+ Scheme: protocol,
+ Host: host,
Path: path,
RawQuery: fmt.Sprintf("limit=%d&min_id=%s", limit, prevMinID),
}
diff --git a/internal/processing/federation/federation.go b/internal/processing/federation/federation.go
index b050406c5..a3e25c2aa 100644
--- a/internal/processing/federation/federation.go
+++ b/internal/processing/federation/federation.go
@@ -24,7 +24,6 @@ import (
"net/url"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
@@ -83,7 +82,6 @@ type Processor interface {
type processor struct {
db db.DB
- config *config.Config
federator federation.Federator
tc typeutils.TypeConverter
filter visibility.Filter
@@ -91,10 +89,9 @@ type processor struct {
}
// New returns a new federation processor.
-func New(db db.DB, tc typeutils.TypeConverter, config *config.Config, federator federation.Federator, fromFederator chan messages.FromFederator) Processor {
+func New(db db.DB, tc typeutils.TypeConverter, federator federation.Federator, fromFederator chan messages.FromFederator) Processor {
return &processor{
db: db,
- config: config,
federator: federator,
tc: tc,
filter: visibility.NewFilter(db),
diff --git a/internal/processing/federation/getnodeinfo.go b/internal/processing/federation/getnodeinfo.go
index 4eb8ad3b7..78e03a744 100644
--- a/internal/processing/federation/getnodeinfo.go
+++ b/internal/processing/federation/getnodeinfo.go
@@ -23,7 +23,9 @@ import (
"fmt"
"net/http"
+ "github.com/spf13/viper"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
@@ -38,29 +40,35 @@ var (
)
func (p *processor) GetNodeInfoRel(ctx context.Context, request *http.Request) (*apimodel.WellKnownResponse, gtserror.WithCode) {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
+
return &apimodel.WellKnownResponse{
Links: []apimodel.Link{
{
Rel: nodeInfoRel,
- Href: fmt.Sprintf("%s://%s/nodeinfo/%s", p.config.Protocol, p.config.Host, nodeInfoVersion),
+ Href: fmt.Sprintf("%s://%s/nodeinfo/%s", protocol, host, nodeInfoVersion),
},
},
}, nil
}
func (p *processor) GetNodeInfo(ctx context.Context, request *http.Request) (*apimodel.Nodeinfo, gtserror.WithCode) {
+ openRegistration := viper.GetBool(config.Keys.AccountsRegistrationOpen)
+ softwareVersion := viper.GetString(config.Keys.SoftwareVersion)
+
return &apimodel.Nodeinfo{
Version: nodeInfoVersion,
Software: apimodel.NodeInfoSoftware{
Name: nodeInfoSoftwareName,
- Version: p.config.SoftwareVersion,
+ Version: softwareVersion,
},
Protocols: nodeInfoProtocols,
Services: apimodel.NodeInfoServices{
Inbound: []string{},
Outbound: []string{},
},
- OpenRegistrations: p.config.AccountsConfig.OpenRegistration,
+ OpenRegistrations: openRegistration,
Usage: apimodel.NodeInfoUsage{
Users: apimodel.NodeInfoUsers{},
},
diff --git a/internal/processing/federation/getwebfinger.go b/internal/processing/federation/getwebfinger.go
index aaa7687be..e16b3e139 100644
--- a/internal/processing/federation/getwebfinger.go
+++ b/internal/processing/federation/getwebfinger.go
@@ -22,7 +22,9 @@ import (
"context"
"fmt"
+ "github.com/spf13/viper"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
)
@@ -41,9 +43,11 @@ func (p *processor) GetWebfingerAccount(ctx context.Context, requestedUsername s
return nil, gtserror.NewErrorNotFound(fmt.Errorf("database error getting account with username %s: %s", requestedUsername, err))
}
+ accountDomain := viper.GetString(config.Keys.AccountDomain)
+
// return the webfinger representation
return &apimodel.WellKnownResponse{
- Subject: fmt.Sprintf("%s:%s@%s", webfingerAccount, requestedAccount.Username, p.config.AccountDomain),
+ Subject: fmt.Sprintf("%s:%s@%s", webfingerAccount, requestedAccount.Username, accountDomain),
Aliases: []string{
requestedAccount.URI,
requestedAccount.URL,
diff --git a/internal/processing/instance.go b/internal/processing/instance.go
index 75d17d13a..995a841e3 100644
--- a/internal/processing/instance.go
+++ b/internal/processing/instance.go
@@ -22,7 +22,9 @@ import (
"context"
"fmt"
+ "github.com/spf13/viper"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -33,7 +35,7 @@ import (
func (p *processor) InstanceGet(ctx context.Context, domain string) (*apimodel.Instance, gtserror.WithCode) {
i := &gtsmodel.Instance{}
if err := p.db.GetWhere(ctx, []db.Where{{Key: "domain", Value: domain}}, i); err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error fetching instance %s: %s", p.config.Host, err))
+ return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error fetching instance %s: %s", domain, err))
}
ai, err := p.tc.InstanceToAPIInstance(ctx, i)
@@ -47,14 +49,15 @@ func (p *processor) InstanceGet(ctx context.Context, domain string) (*apimodel.I
func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSettingsUpdateRequest) (*apimodel.Instance, gtserror.WithCode) {
// fetch the instance entry from the db for processing
i := &gtsmodel.Instance{}
- if err := p.db.GetWhere(ctx, []db.Where{{Key: "domain", Value: p.config.Host}}, i); err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error fetching instance %s: %s", p.config.Host, err))
+ host := viper.GetString(config.Keys.Host)
+ if err := p.db.GetWhere(ctx, []db.Where{{Key: "domain", Value: host}}, i); err != nil {
+ return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error fetching instance %s: %s", host, err))
}
// fetch the instance account from the db for processing
ia, err := p.db.GetInstanceAccount(ctx, "")
if err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error fetching instance account %s: %s", p.config.Host, err))
+ return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error fetching instance account %s: %s", host, err))
}
// validate & update site title if it's set on the form
@@ -148,7 +151,7 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe
}
if err := p.db.UpdateByPrimaryKey(ctx, i); err != nil {
- return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error updating instance %s: %s", p.config.Host, err))
+ return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error updating instance %s: %s", host, err))
}
ai, err := p.tc.InstanceToAPIInstance(ctx, i)
diff --git a/internal/processing/media/media.go b/internal/processing/media/media.go
index cf8ec8562..54dbd1478 100644
--- a/internal/processing/media/media.go
+++ b/internal/processing/media/media.go
@@ -23,7 +23,6 @@ import (
"codeberg.org/gruf/go-store/kv"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -44,17 +43,15 @@ type Processor interface {
type processor struct {
tc typeutils.TypeConverter
- config *config.Config
mediaHandler media.Handler
storage *kv.KVStore
db db.DB
}
// New returns a new media processor.
-func New(db db.DB, tc typeutils.TypeConverter, mediaHandler media.Handler, storage *kv.KVStore, config *config.Config) Processor {
+func New(db db.DB, tc typeutils.TypeConverter, mediaHandler media.Handler, storage *kv.KVStore) Processor {
return &processor{
tc: tc,
- config: config,
mediaHandler: mediaHandler,
storage: storage,
db: db,
diff --git a/internal/processing/processor.go b/internal/processing/processor.go
index a65ef23d9..ebfabb0de 100644
--- a/internal/processing/processor.go
+++ b/internal/processing/processor.go
@@ -26,7 +26,6 @@ import (
"codeberg.org/gruf/go-store/kv"
"github.com/sirupsen/logrus"
apimodel "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"
@@ -234,7 +233,6 @@ type processor struct {
fromFederator chan messages.FromFederator
federator federation.Federator
stop chan interface{}
- config *config.Config
tc typeutils.TypeConverter
oauthServer oauth.Server
mediaHandler media.Handler
@@ -258,7 +256,6 @@ type processor struct {
// NewProcessor returns a new Processor.
func NewProcessor(
- config *config.Config,
tc typeutils.TypeConverter,
federator federation.Federator,
oauthServer oauth.Server,
@@ -270,20 +267,19 @@ func NewProcessor(
fromClientAPI := make(chan messages.FromClientAPI, 1000)
fromFederator := make(chan messages.FromFederator, 1000)
- statusProcessor := status.New(db, tc, config, fromClientAPI)
+ statusProcessor := status.New(db, tc, fromClientAPI)
streamingProcessor := streaming.New(db, oauthServer)
- accountProcessor := account.New(db, tc, mediaHandler, oauthServer, fromClientAPI, federator, config)
- adminProcessor := admin.New(db, tc, mediaHandler, fromClientAPI, config)
- mediaProcessor := mediaProcessor.New(db, tc, mediaHandler, storage, config)
- userProcessor := user.New(db, emailSender, config)
- federationProcessor := federationProcessor.New(db, tc, config, federator, fromFederator)
+ accountProcessor := account.New(db, tc, mediaHandler, oauthServer, fromClientAPI, federator)
+ adminProcessor := admin.New(db, tc, mediaHandler, fromClientAPI)
+ mediaProcessor := mediaProcessor.New(db, tc, mediaHandler, storage)
+ userProcessor := user.New(db, emailSender)
+ federationProcessor := federationProcessor.New(db, tc, federator, fromFederator)
return &processor{
fromClientAPI: fromClientAPI,
fromFederator: fromFederator,
federator: federator,
stop: make(chan interface{}),
- config: config,
tc: tc,
oauthServer: oauthServer,
mediaHandler: mediaHandler,
diff --git a/internal/processing/processor_test.go b/internal/processing/processor_test.go
index 181cfa63a..2ed1e1d44 100644
--- a/internal/processing/processor_test.go
+++ b/internal/processing/processor_test.go
@@ -29,7 +29,6 @@ import (
"codeberg.org/gruf/go-store/kv"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/activity/streams"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/email"
"github.com/superseriousbusiness/gotosocial/internal/federation"
@@ -46,7 +45,6 @@ import (
type ProcessingStandardTestSuite struct {
// standard suite interfaces
suite.Suite
- config *config.Config
db db.DB
storage *kv.KVStore
typeconverter typeutils.TypeConverter
@@ -93,14 +91,15 @@ func (suite *ProcessingStandardTestSuite) SetupSuite() {
Account: suite.testAccounts["local_account_1"],
},
}
- suite.testActivities = testrig.NewTestActivities(suite.testAccounts)
suite.testBlocks = testrig.NewTestBlocks()
}
func (suite *ProcessingStandardTestSuite) SetupTest() {
testrig.InitTestLog()
- suite.config = testrig.NewTestConfig()
+ testrig.InitTestConfig()
+
suite.db = testrig.NewTestDB()
+ suite.testActivities = testrig.NewTestActivities(suite.testAccounts)
suite.storage = testrig.NewTestStorage()
suite.typeconverter = testrig.NewTestTypeConverter(suite.db)
@@ -223,7 +222,7 @@ func (suite *ProcessingStandardTestSuite) SetupTest() {
suite.timelineManager = testrig.NewTestTimelineManager(suite.db)
suite.emailSender = testrig.NewEmailSender("../../web/template/", nil)
- suite.processor = processing.NewProcessor(suite.config, suite.typeconverter, suite.federator, suite.oauthServer, suite.mediaHandler, suite.storage, suite.timelineManager, suite.db, suite.emailSender)
+ suite.processor = processing.NewProcessor(suite.typeconverter, suite.federator, suite.oauthServer, suite.mediaHandler, suite.storage, suite.timelineManager, suite.db, suite.emailSender)
testrig.StandardDBSetup(suite.db, suite.testAccounts)
testrig.StandardStorageSetup(suite.storage, "../../testrig/media")
diff --git a/internal/processing/search.go b/internal/processing/search.go
index fbcfb02be..a7a2b3109 100644
--- a/internal/processing/search.go
+++ b/internal/processing/search.go
@@ -25,7 +25,9 @@ import (
"strings"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -164,7 +166,8 @@ func (p *processor) searchAccountByMention(ctx context.Context, authed *oauth.Au
// if it's a local account we can skip a whole bunch of stuff
maybeAcct := &gtsmodel.Account{}
- if domain == p.config.Host {
+ host := viper.GetString(config.Keys.Host)
+ if domain == host {
maybeAcct, err = p.db.GetLocalAccountByUsername(ctx, username)
if err != nil {
return nil, fmt.Errorf("searchAccountByMention: error getting local account by username: %s", err)
diff --git a/internal/processing/status/create.go b/internal/processing/status/create.go
index 655be5b17..9bcb32b78 100644
--- a/internal/processing/status/create.go
+++ b/internal/processing/status/create.go
@@ -34,7 +34,7 @@ import (
)
func (p *processor) Create(ctx context.Context, account *gtsmodel.Account, application *gtsmodel.Application, form *apimodel.AdvancedStatusCreateForm) (*apimodel.Status, gtserror.WithCode) {
- uris := util.GenerateURIsForAccount(account.Username, p.config.Protocol, p.config.Host)
+ uris := util.GenerateURIsForAccount(account.Username)
thisStatusID, err := id.NewULID()
if err != nil {
return nil, gtserror.NewErrorInternalError(err)
diff --git a/internal/processing/status/fave.go b/internal/processing/status/fave.go
index 571e0715c..581caf055 100644
--- a/internal/processing/status/fave.go
+++ b/internal/processing/status/fave.go
@@ -76,7 +76,7 @@ func (p *processor) Fave(ctx context.Context, requestingAccount *gtsmodel.Accoun
TargetAccount: targetStatus.Account,
StatusID: targetStatus.ID,
Status: targetStatus,
- URI: util.GenerateURIForLike(requestingAccount.Username, p.config.Protocol, p.config.Host, thisFaveID),
+ URI: util.GenerateURIForLike(requestingAccount.Username, thisFaveID),
}
if err := p.db.Put(ctx, gtsFave); err != nil {
diff --git a/internal/processing/status/status.go b/internal/processing/status/status.go
index 666c237b7..da0abd6f4 100644
--- a/internal/processing/status/status.go
+++ b/internal/processing/status/status.go
@@ -22,7 +22,6 @@ import (
"context"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -71,7 +70,6 @@ type Processor interface {
type processor struct {
tc typeutils.TypeConverter
- config *config.Config
db db.DB
filter visibility.Filter
formatter text.Formatter
@@ -79,13 +77,12 @@ type processor struct {
}
// New returns a new status processor.
-func New(db db.DB, tc typeutils.TypeConverter, config *config.Config, fromClientAPI chan messages.FromClientAPI) Processor {
+func New(db db.DB, tc typeutils.TypeConverter, fromClientAPI chan messages.FromClientAPI) Processor {
return &processor{
tc: tc,
- config: config,
db: db,
filter: visibility.NewFilter(db),
- formatter: text.NewFormatter(config, db),
+ formatter: text.NewFormatter(db),
fromClientAPI: fromClientAPI,
}
}
diff --git a/internal/processing/status/status_test.go b/internal/processing/status/status_test.go
index c5c439057..2ed37bf2a 100644
--- a/internal/processing/status/status_test.go
+++ b/internal/processing/status/status_test.go
@@ -20,18 +20,16 @@ package status_test
import (
"github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/messages"
"github.com/superseriousbusiness/gotosocial/internal/processing/status"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
+ "github.com/superseriousbusiness/gotosocial/testrig"
)
-// nolint
type StatusStandardTestSuite struct {
suite.Suite
- config *config.Config
db db.DB
typeConverter typeutils.TypeConverter
fromClientAPIChan chan messages.FromClientAPI
@@ -50,3 +48,31 @@ type StatusStandardTestSuite struct {
// module being tested
status status.Processor
}
+
+func (suite *StatusStandardTestSuite) SetupSuite() {
+ suite.testTokens = testrig.NewTestTokens()
+ suite.testClients = testrig.NewTestClients()
+ suite.testApplications = testrig.NewTestApplications()
+ suite.testUsers = testrig.NewTestUsers()
+ suite.testAccounts = testrig.NewTestAccounts()
+ suite.testAttachments = testrig.NewTestAttachments()
+ suite.testStatuses = testrig.NewTestStatuses()
+ suite.testTags = testrig.NewTestTags()
+ suite.testMentions = testrig.NewTestMentions()
+}
+
+func (suite *StatusStandardTestSuite) SetupTest() {
+ testrig.InitTestLog()
+ testrig.InitTestConfig()
+
+ suite.db = testrig.NewTestDB()
+ suite.typeConverter = testrig.NewTestTypeConverter(suite.db)
+ suite.fromClientAPIChan = make(chan messages.FromClientAPI, 100)
+ suite.status = status.New(suite.db, suite.typeConverter, suite.fromClientAPIChan)
+
+ testrig.StandardDBSetup(suite.db, nil)
+}
+
+func (suite *StatusStandardTestSuite) TearDownTest() {
+ testrig.StandardDBTeardown(suite.db)
+}
diff --git a/internal/processing/status/util_test.go b/internal/processing/status/util_test.go
index 37e2f2dfc..4ec66a4f7 100644
--- a/internal/processing/status/util_test.go
+++ b/internal/processing/status/util_test.go
@@ -27,9 +27,6 @@ import (
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/api/model"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
- "github.com/superseriousbusiness/gotosocial/internal/messages"
- "github.com/superseriousbusiness/gotosocial/internal/processing/status"
- "github.com/superseriousbusiness/gotosocial/testrig"
)
const statusText1 = `Another test @foss_satan@fossbros-anonymous.io
@@ -52,33 +49,6 @@ type UtilTestSuite struct {
StatusStandardTestSuite
}
-func (suite *UtilTestSuite) SetupSuite() {
- suite.testTokens = testrig.NewTestTokens()
- suite.testClients = testrig.NewTestClients()
- suite.testApplications = testrig.NewTestApplications()
- suite.testUsers = testrig.NewTestUsers()
- suite.testAccounts = testrig.NewTestAccounts()
- suite.testAttachments = testrig.NewTestAttachments()
- suite.testStatuses = testrig.NewTestStatuses()
- suite.testTags = testrig.NewTestTags()
- suite.testMentions = testrig.NewTestMentions()
-}
-
-func (suite *UtilTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
- suite.db = testrig.NewTestDB()
- testrig.InitTestLog()
- suite.typeConverter = testrig.NewTestTypeConverter(suite.db)
- suite.fromClientAPIChan = make(chan messages.FromClientAPI, 100)
- suite.status = status.New(suite.db, suite.typeConverter, suite.config, suite.fromClientAPIChan)
-
- testrig.StandardDBSetup(suite.db, nil)
-}
-
-func (suite *UtilTestSuite) TearDownTest() {
- testrig.StandardDBTeardown(suite.db)
-}
-
func (suite *UtilTestSuite) TestProcessMentions1() {
creatingAccount := suite.testAccounts["local_account_1"]
mentionedAccount := suite.testAccounts["remote_account_1"]
diff --git a/internal/processing/streaming/streaming_test.go b/internal/processing/streaming/streaming_test.go
index cbb899d12..ac143636f 100644
--- a/internal/processing/streaming/streaming_test.go
+++ b/internal/processing/streaming/streaming_test.go
@@ -38,11 +38,13 @@ type StreamingTestSuite struct {
}
func (suite *StreamingTestSuite) SetupTest() {
+ testrig.InitTestLog()
+ testrig.InitTestConfig()
+
suite.testAccounts = testrig.NewTestAccounts()
suite.testTokens = testrig.NewTestTokens()
suite.db = testrig.NewTestDB()
suite.oauthServer = testrig.NewTestOauthServer(suite.db)
- testrig.InitTestLog()
suite.streamingProcessor = streaming.New(suite.db, suite.oauthServer)
testrig.StandardDBSetup(suite.db, suite.testAccounts)
diff --git a/internal/processing/timeline.go b/internal/processing/timeline.go
index 64238225f..b3a4a80ae 100644
--- a/internal/processing/timeline.go
+++ b/internal/processing/timeline.go
@@ -21,10 +21,13 @@ package processing
import (
"context"
"fmt"
- "github.com/sirupsen/logrus"
"net/url"
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
+
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -39,17 +42,20 @@ func (p *processor) packageStatusResponse(statuses []*apimodel.Status, path stri
// prepare the next and previous links
if len(statuses) != 0 {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
+
nextLink := &url.URL{
- Scheme: p.config.Protocol,
- Host: p.config.Host,
+ Scheme: protocol,
+ Host: host,
Path: path,
RawQuery: fmt.Sprintf("limit=%d&max_id=%s", limit, nextMaxID),
}
next := fmt.Sprintf("<%s>; rel=\"next\"", nextLink.String())
prevLink := &url.URL{
- Scheme: p.config.Protocol,
- Host: p.config.Host,
+ Scheme: protocol,
+ Host: host,
Path: path,
RawQuery: fmt.Sprintf("limit=%d&min_id=%s", limit, prevMinID),
}
diff --git a/internal/processing/user/emailconfirm.go b/internal/processing/user/emailconfirm.go
index 1f9cb0a10..3e19c61d4 100644
--- a/internal/processing/user/emailconfirm.go
+++ b/internal/processing/user/emailconfirm.go
@@ -25,6 +25,8 @@ import (
"time"
"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/email"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
@@ -51,11 +53,12 @@ func (p *processor) SendConfirmEmail(ctx context.Context, user *gtsmodel.User, u
// equivalent to the odds of creating a few tens of trillions of UUIDs in a
// year and having one duplicate.
confirmationToken := uuid.NewString()
- confirmationLink := util.GenerateURIForEmailConfirm(p.config.Protocol, p.config.Host, confirmationToken)
+ confirmationLink := util.GenerateURIForEmailConfirm(confirmationToken)
// pull our instance entry from the database so we can greet the user nicely in the email
instance := &gtsmodel.Instance{}
- if err := p.db.GetWhere(ctx, []db.Where{{Key: "domain", Value: p.config.Host}}, instance); err != nil {
+ host := viper.GetString(config.Keys.Host)
+ if err := p.db.GetWhere(ctx, []db.Where{{Key: "domain", Value: host}}, instance); err != nil {
return fmt.Errorf("SendConfirmEmail: error getting instance: %s", err)
}
diff --git a/internal/processing/user/user.go b/internal/processing/user/user.go
index 73cdb4901..2ddf12d7b 100644
--- a/internal/processing/user/user.go
+++ b/internal/processing/user/user.go
@@ -21,7 +21,6 @@ package user
import (
"context"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/email"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
@@ -40,15 +39,13 @@ type Processor interface {
}
type processor struct {
- config *config.Config
emailSender email.Sender
db db.DB
}
// New returns a new user processor
-func New(db db.DB, emailSender email.Sender, config *config.Config) Processor {
+func New(db db.DB, emailSender email.Sender) Processor {
return &processor{
- config: config,
emailSender: emailSender,
db: db,
}
diff --git a/internal/processing/user/user_test.go b/internal/processing/user/user_test.go
index 5c3cd7597..f9514d720 100644
--- a/internal/processing/user/user_test.go
+++ b/internal/processing/user/user_test.go
@@ -20,7 +20,6 @@ package user_test
import (
"github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/email"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
@@ -30,7 +29,6 @@ import (
type UserStandardTestSuite struct {
suite.Suite
- config *config.Config
emailSender email.Sender
db db.DB
@@ -43,13 +41,14 @@ type UserStandardTestSuite struct {
func (suite *UserStandardTestSuite) SetupTest() {
testrig.InitTestLog()
- suite.config = testrig.NewTestConfig()
+ testrig.InitTestConfig()
+
suite.db = testrig.NewTestDB()
suite.sentEmails = make(map[string]string)
suite.emailSender = testrig.NewEmailSender("../../../web/template/", suite.sentEmails)
suite.testUsers = testrig.NewTestUsers()
- suite.user = user.New(suite.db, suite.emailSender, suite.config)
+ suite.user = user.New(suite.db, suite.emailSender)
testrig.StandardDBSetup(suite.db, nil)
}
diff --git a/internal/router/cors.go b/internal/router/cors.go
index 9f8d379dd..e2ce9ce87 100644
--- a/internal/router/cors.go
+++ b/internal/router/cors.go
@@ -23,7 +23,6 @@ import (
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
- "github.com/superseriousbusiness/gotosocial/internal/config"
)
var corsConfig = cors.Config{
@@ -81,7 +80,7 @@ var corsConfig = cors.Config{
}
// useCors attaches the corsConfig above to the given gin engine
-func useCors(cfg *config.Config, engine *gin.Engine) error {
+func useCors(engine *gin.Engine) error {
c := cors.New(corsConfig)
engine.Use(c)
return nil
diff --git a/internal/router/router.go b/internal/router/router.go
index aef5c32e4..aa588906f 100644
--- a/internal/router/router.go
+++ b/internal/router/router.go
@@ -26,6 +26,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"golang.org/x/crypto/acme/autocert"
@@ -58,7 +59,6 @@ type Router interface {
type router struct {
engine *gin.Engine
srv *http.Server
- config *config.Config
certManager *autocert.Manager
}
@@ -69,10 +69,16 @@ func (r *router) AttachStaticFS(relativePath string, fs http.FileSystem) {
// Start starts the router nicely. It will serve two handlers if letsencrypt is enabled, and only the web/API handler if letsencrypt is not enabled.
func (r *router) Start() {
- if r.config.LetsEncryptConfig.Enabled {
+ keys := config.Keys
+ leEnabled := viper.GetBool(keys.LetsEncryptEnabled)
+
+ if leEnabled {
+ bindAddress := viper.GetString(keys.BindAddress)
+ lePort := viper.GetInt(keys.LetsEncryptPort)
+
// serve the http handler on the selected letsencrypt port, for receiving letsencrypt requests and solving their devious riddles
go func() {
- listen := fmt.Sprintf("%s:%d", r.config.BindAddress, r.config.LetsEncryptConfig.Port)
+ listen := fmt.Sprintf("%s:%d", bindAddress, lePort)
if err := http.ListenAndServe(listen, r.certManager.HTTPHandler(http.HandlerFunc(httpsRedirect))); err != nil && err != http.ErrServerClosed {
logrus.Fatalf("listen: %s", err)
}
@@ -103,7 +109,9 @@ func (r *router) Stop(ctx context.Context) error {
//
// The given DB is only used in the New function for parsing config values, and is not otherwise
// pinned to the router.
-func New(ctx context.Context, cfg *config.Config, db db.DB) (Router, error) {
+func New(ctx context.Context, db db.DB) (Router, error) {
+ keys := config.Keys
+
gin.SetMode(gin.ReleaseMode)
// create the actual engine here -- this is the core request routing handler for gts
@@ -116,12 +124,13 @@ func New(ctx context.Context, cfg *config.Config, db db.DB) (Router, error) {
engine.MaxMultipartMemory = 8 << 20
// set up IP forwarding via x-forward-* headers.
- if err := engine.SetTrustedProxies(cfg.TrustedProxies); err != nil {
+ trustedProxies := viper.GetStringSlice(keys.TrustedProxies)
+ if err := engine.SetTrustedProxies(trustedProxies); err != nil {
return nil, err
}
// enable cors on the engine
- if err := useCors(cfg, engine); err != nil {
+ if err := useCors(engine); err != nil {
return nil, err
}
@@ -129,17 +138,19 @@ func New(ctx context.Context, cfg *config.Config, db db.DB) (Router, error) {
loadTemplateFunctions(engine)
// load templates onto the engine
- if err := loadTemplates(cfg, engine); err != nil {
+ if err := loadTemplates(engine); err != nil {
return nil, err
}
// enable session store middleware on the engine
- if err := useSession(ctx, cfg, db, engine); err != nil {
+ if err := useSession(ctx, db, engine); err != nil {
return nil, err
}
// create the http server here, passing the gin engine as handler
- listen := fmt.Sprintf("%s:%d", cfg.BindAddress, cfg.Port)
+ bindAddress := viper.GetString(keys.BindAddress)
+ port := viper.GetInt(keys.Port)
+ listen := fmt.Sprintf("%s:%d", bindAddress, port)
s := &http.Server{
Addr: listen,
Handler: engine,
@@ -151,15 +162,19 @@ func New(ctx context.Context, cfg *config.Config, db db.DB) (Router, error) {
// We need to spawn the underlying server slightly differently depending on whether lets encrypt is enabled or not.
// In either case, the gin engine will still be used for routing requests.
+ leEnabled := viper.GetBool(keys.LetsEncryptEnabled)
var m *autocert.Manager
- if cfg.LetsEncryptConfig.Enabled {
+ if leEnabled {
// le IS enabled, so roll up an autocert manager for handling letsencrypt requests
+ host := viper.GetString(keys.Host)
+ leCertDir := viper.GetString(keys.LetsEncryptCertDir)
+ leEmailAddress := viper.GetString(keys.LetsEncryptEmailAddress)
m = &autocert.Manager{
Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist(cfg.Host),
- Cache: autocert.DirCache(cfg.LetsEncryptConfig.CertDir),
- Email: cfg.LetsEncryptConfig.EmailAddress,
+ HostPolicy: autocert.HostWhitelist(host),
+ Cache: autocert.DirCache(leCertDir),
+ Email: leEmailAddress,
}
s.TLSConfig = m.TLSConfig()
}
@@ -167,7 +182,6 @@ func New(ctx context.Context, cfg *config.Config, db db.DB) (Router, error) {
return &router{
engine: engine,
srv: s,
- config: cfg,
certManager: m,
}, nil
}
diff --git a/internal/router/session.go b/internal/router/session.go
index 3276c38aa..1f7b8bcfa 100644
--- a/internal/router/session.go
+++ b/internal/router/session.go
@@ -28,15 +28,16 @@ import (
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/memstore"
"github.com/gin-gonic/gin"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
)
// sessionOptions returns the standard set of options to use for each session.
-func sessionOptions(cfg *config.Config) sessions.Options {
+func sessionOptions() sessions.Options {
return sessions.Options{
Path: "/",
- Domain: cfg.Host,
+ Domain: viper.GetString(config.Keys.Host),
MaxAge: 120, // 2 minutes
Secure: true, // only use cookie over https
HttpOnly: true, // exclude javascript from inspecting cookie
@@ -44,9 +45,12 @@ func sessionOptions(cfg *config.Config) sessions.Options {
}
}
-func sessionName(cfg *config.Config) (string, error) {
+// SessionName is a utility function that derives an appropriate session name from the hostname.
+func SessionName() (string, error) {
// parse the protocol + host
- u, err := url.Parse(fmt.Sprintf("%s://%s", cfg.Protocol, cfg.Host))
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
+ u, err := url.Parse(fmt.Sprintf("%s://%s", protocol, host))
if err != nil {
return "", err
}
@@ -54,13 +58,13 @@ func sessionName(cfg *config.Config) (string, error) {
// take the hostname without any port attached
strippedHostname := u.Hostname()
if strippedHostname == "" {
- return "", fmt.Errorf("could not derive hostname without port from %s://%s", cfg.Protocol, cfg.Host)
+ return "", fmt.Errorf("could not derive hostname without port from %s://%s", protocol, host)
}
return fmt.Sprintf("gotosocial-%s", strippedHostname), nil
}
-func useSession(ctx context.Context, cfg *config.Config, sessionDB db.Session, engine *gin.Engine) error {
+func useSession(ctx context.Context, sessionDB db.Session, engine *gin.Engine) error {
// check if we have a saved router session already
rs, err := sessionDB.GetSession(ctx)
if err != nil {
@@ -71,9 +75,9 @@ func useSession(ctx context.Context, cfg *config.Config, sessionDB db.Session, e
}
store := memstore.NewStore(rs.Auth, rs.Crypt)
- store.Options(sessionOptions(cfg))
+ store.Options(sessionOptions())
- sessionName, err := sessionName(cfg)
+ sessionName, err := SessionName()
if err != nil {
return err
}
diff --git a/internal/router/session_test.go b/internal/router/session_test.go
index 7c2d324fd..31beec1ae 100644
--- a/internal/router/session_test.go
+++ b/internal/router/session_test.go
@@ -16,68 +16,68 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package router
+package router_test
import (
"testing"
+ "github.com/spf13/viper"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/config"
+ "github.com/superseriousbusiness/gotosocial/internal/router"
+ "github.com/superseriousbusiness/gotosocial/testrig"
)
type SessionTestSuite struct {
suite.Suite
}
+func (suite *SessionTestSuite) SetupTest() {
+ testrig.InitTestConfig()
+}
+
func (suite *SessionTestSuite) TestDeriveSessionNameLocalhostWithPort() {
- cfg := &config.Config{
- Protocol: "http",
- Host: "localhost:8080",
- }
+ viper.Set(config.Keys.Protocol, "http")
+ viper.Set(config.Keys.Host, "localhost:8080")
- sessionName, err := sessionName(cfg)
+ sessionName, err := router.SessionName()
suite.NoError(err)
suite.Equal("gotosocial-localhost", sessionName)
}
func (suite *SessionTestSuite) TestDeriveSessionNameLocalhost() {
- cfg := &config.Config{
- Protocol: "http",
- Host: "localhost",
- }
+ viper.Set(config.Keys.Protocol, "http")
+ viper.Set(config.Keys.Host, "localhost")
- sessionName, err := sessionName(cfg)
+ sessionName, err := router.SessionName()
suite.NoError(err)
suite.Equal("gotosocial-localhost", sessionName)
}
func (suite *SessionTestSuite) TestDeriveSessionNoProtocol() {
- cfg := &config.Config{
- Host: "localhost",
- }
+ viper.Set(config.Keys.Protocol, "")
+ viper.Set(config.Keys.Host, "localhost")
- sessionName, err := sessionName(cfg)
+ sessionName, err := router.SessionName()
suite.EqualError(err, "parse \"://localhost\": missing protocol scheme")
suite.Equal("", sessionName)
}
func (suite *SessionTestSuite) TestDeriveSessionNoHost() {
- cfg := &config.Config{
- Protocol: "https",
- }
+ viper.Set(config.Keys.Protocol, "https")
+ viper.Set(config.Keys.Host, "")
+ viper.Set(config.Keys.Port, 0)
- sessionName, err := sessionName(cfg)
+ sessionName, err := router.SessionName()
suite.EqualError(err, "could not derive hostname without port from https://")
suite.Equal("", sessionName)
}
func (suite *SessionTestSuite) TestDeriveSessionOK() {
- cfg := &config.Config{
- Protocol: "https",
- Host: "example.org",
- }
+ viper.Set(config.Keys.Protocol, "https")
+ viper.Set(config.Keys.Host, "example.org")
- sessionName, err := sessionName(cfg)
+ sessionName, err := router.SessionName()
suite.NoError(err)
suite.Equal("gotosocial-example.org", sessionName)
}
diff --git a/internal/router/template.go b/internal/router/template.go
index bf5682628..b0d998208 100644
--- a/internal/router/template.go
+++ b/internal/router/template.go
@@ -26,18 +26,20 @@ import (
"time"
"github.com/gin-gonic/gin"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/api/model"
"github.com/superseriousbusiness/gotosocial/internal/config"
)
// loadTemplates loads html templates for use by the given engine
-func loadTemplates(cfg *config.Config, engine *gin.Engine) error {
+func loadTemplates(engine *gin.Engine) error {
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("error getting current working directory: %s", err)
}
- tmPath := filepath.Join(cwd, fmt.Sprintf("%s*", cfg.TemplateConfig.BaseDir))
+ templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir)
+ tmPath := filepath.Join(cwd, fmt.Sprintf("%s*", templateBaseDir))
engine.LoadHTMLGlob(tmPath)
return nil
diff --git a/internal/text/formatter.go b/internal/text/formatter.go
index b0988e9f9..f7c908a7d 100644
--- a/internal/text/formatter.go
+++ b/internal/text/formatter.go
@@ -21,7 +21,6 @@ package text
import (
"context"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
)
@@ -42,14 +41,12 @@ type Formatter interface {
}
type formatter struct {
- cfg *config.Config
- db db.DB
+ db db.DB
}
// NewFormatter returns a new Formatter interface for parsing statuses and other text input into nice html.
-func NewFormatter(cfg *config.Config, db db.DB) Formatter {
+func NewFormatter(db db.DB) Formatter {
return &formatter{
- cfg: cfg,
- db: db,
+ db: db,
}
}
diff --git a/internal/text/formatter_test.go b/internal/text/formatter_test.go
index 8b4d176e2..096d32789 100644
--- a/internal/text/formatter_test.go
+++ b/internal/text/formatter_test.go
@@ -20,7 +20,6 @@ package text_test
import (
"github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/text"
@@ -30,8 +29,7 @@ import (
type TextStandardTestSuite struct {
// standard suite interfaces
suite.Suite
- config *config.Config
- db db.DB
+ db db.DB
// standard suite models
testTokens map[string]*gtsmodel.Token
@@ -61,9 +59,11 @@ func (suite *TextStandardTestSuite) SetupSuite() {
}
func (suite *TextStandardTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
+ testrig.InitTestLog()
+ testrig.InitTestConfig()
+
suite.db = testrig.NewTestDB()
- suite.formatter = text.NewFormatter(suite.config, suite.db)
+ suite.formatter = text.NewFormatter(suite.db)
testrig.StandardDBSetup(suite.db, nil)
}
diff --git a/internal/timeline/get_test.go b/internal/timeline/get_test.go
index b05585cab..cebb9033f 100644
--- a/internal/timeline/get_test.go
+++ b/internal/timeline/get_test.go
@@ -38,9 +38,10 @@ func (suite *GetTestSuite) SetupSuite() {
}
func (suite *GetTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
- suite.db = testrig.NewTestDB()
testrig.InitTestLog()
+ testrig.InitTestConfig()
+
+ suite.db = testrig.NewTestDB()
suite.tc = testrig.NewTestTypeConverter(suite.db)
testrig.StandardDBSetup(suite.db, nil)
diff --git a/internal/timeline/index_test.go b/internal/timeline/index_test.go
index 0f3a1df4a..a326f223e 100644
--- a/internal/timeline/index_test.go
+++ b/internal/timeline/index_test.go
@@ -39,9 +39,10 @@ func (suite *IndexTestSuite) SetupSuite() {
}
func (suite *IndexTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
- suite.db = testrig.NewTestDB()
testrig.InitTestLog()
+ testrig.InitTestConfig()
+
+ suite.db = testrig.NewTestDB()
suite.tc = testrig.NewTestTypeConverter(suite.db)
testrig.StandardDBSetup(suite.db, nil)
diff --git a/internal/timeline/manager.go b/internal/timeline/manager.go
index 5d41d72a9..c5b10921b 100644
--- a/internal/timeline/manager.go
+++ b/internal/timeline/manager.go
@@ -26,7 +26,6 @@ import (
"github.com/sirupsen/logrus"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
@@ -84,12 +83,11 @@ type Manager interface {
}
// NewManager returns a new timeline manager with the given database, typeconverter, config, and log.
-func NewManager(db db.DB, tc typeutils.TypeConverter, config *config.Config) Manager {
+func NewManager(db db.DB, tc typeutils.TypeConverter) Manager {
return &manager{
accountTimelines: sync.Map{},
db: db,
tc: tc,
- config: config,
}
}
@@ -97,7 +95,6 @@ type manager struct {
accountTimelines sync.Map
db db.DB
tc typeutils.TypeConverter
- config *config.Config
}
func (m *manager) Ingest(ctx context.Context, status *gtsmodel.Status, timelineAccountID string) (bool, error) {
diff --git a/internal/timeline/manager_test.go b/internal/timeline/manager_test.go
index 4d725e48d..f5d62fe42 100644
--- a/internal/timeline/manager_test.go
+++ b/internal/timeline/manager_test.go
@@ -36,9 +36,10 @@ func (suite *ManagerTestSuite) SetupSuite() {
}
func (suite *ManagerTestSuite) SetupTest() {
- suite.config = testrig.NewTestConfig()
- suite.db = testrig.NewTestDB()
testrig.InitTestLog()
+ testrig.InitTestConfig()
+
+ suite.db = testrig.NewTestDB()
suite.tc = testrig.NewTestTypeConverter(suite.db)
testrig.StandardDBSetup(suite.db, nil)
diff --git a/internal/timeline/timeline_test.go b/internal/timeline/timeline_test.go
index 517575f3e..8ef407711 100644
--- a/internal/timeline/timeline_test.go
+++ b/internal/timeline/timeline_test.go
@@ -20,7 +20,6 @@ package timeline_test
import (
"github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/timeline"
@@ -29,9 +28,8 @@ import (
type TimelineStandardTestSuite struct {
suite.Suite
- config *config.Config
- db db.DB
- tc typeutils.TypeConverter
+ db db.DB
+ tc typeutils.TypeConverter
testAccounts map[string]*gtsmodel.Account
testStatuses map[string]*gtsmodel.Status
diff --git a/internal/trans/trans_test.go b/internal/trans/trans_test.go
index 6554167b0..a6669f397 100644
--- a/internal/trans/trans_test.go
+++ b/internal/trans/trans_test.go
@@ -30,8 +30,9 @@ type TransTestSuite struct {
}
func (suite *TransTestSuite) SetupTest() {
- suite.db = testrig.NewTestDB()
testrig.InitTestLog()
+ testrig.InitTestConfig()
+ suite.db = testrig.NewTestDB()
testrig.StandardDBSetup(suite.db, nil)
}
diff --git a/internal/transport/controller.go b/internal/transport/controller.go
index 86f612c15..1f46494dc 100644
--- a/internal/transport/controller.go
+++ b/internal/transport/controller.go
@@ -25,6 +25,7 @@ import (
"sync"
"github.com/go-fed/httpsig"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
@@ -37,7 +38,6 @@ type Controller interface {
}
type controller struct {
- config *config.Config
db db.DB
clock pub.Clock
client pub.HttpClient
@@ -45,13 +45,16 @@ type controller struct {
}
// NewController returns an implementation of the Controller interface for creating new transports
-func NewController(config *config.Config, db db.DB, clock pub.Clock, client pub.HttpClient) Controller {
+func NewController(db db.DB, clock pub.Clock, client pub.HttpClient) Controller {
+ applicationName := viper.GetString(config.Keys.ApplicationName)
+ host := viper.GetString(config.Keys.Host)
+ appAgent := fmt.Sprintf("%s %s", applicationName, host)
+
return &controller{
- config: config,
db: db,
clock: clock,
client: client,
- appAgent: fmt.Sprintf("%s %s", config.ApplicationName, config.Host),
+ appAgent: appAgent,
}
}
@@ -93,7 +96,7 @@ func (c *controller) NewTransportForUsername(ctx context.Context, username strin
// Otherwise, we can take the instance account and use those credentials to make the request.
var u string
if username == "" {
- u = c.config.Host
+ u = viper.GetString(config.Keys.Host)
} else {
u = username
}
diff --git a/internal/typeutils/converter.go b/internal/typeutils/converter.go
index 212ae1247..448fef5c8 100644
--- a/internal/typeutils/converter.go
+++ b/internal/typeutils/converter.go
@@ -26,7 +26,6 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/ap"
"github.com/superseriousbusiness/gotosocial/internal/api/model"
"github.com/superseriousbusiness/gotosocial/internal/cache"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
)
@@ -192,15 +191,13 @@ type TypeConverter interface {
}
type converter struct {
- config *config.Config
db db.DB
asCache cache.Cache
}
// NewConverter returns a new Converter
-func NewConverter(config *config.Config, db db.DB) TypeConverter {
+func NewConverter(db db.DB) TypeConverter {
return &converter{
- config: config,
db: db,
asCache: cache.New(),
}
diff --git a/internal/typeutils/converter_test.go b/internal/typeutils/converter_test.go
index d557e52f2..57952a84a 100644
--- a/internal/typeutils/converter_test.go
+++ b/internal/typeutils/converter_test.go
@@ -21,7 +21,6 @@ package typeutils_test
import (
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/activity/streams/vocab"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
@@ -324,7 +323,6 @@ const (
type TypeUtilsTestSuite struct {
suite.Suite
- config *config.Config
db db.DB
testAccounts map[string]*gtsmodel.Account
testStatuses map[string]*gtsmodel.Status
@@ -334,13 +332,14 @@ type TypeUtilsTestSuite struct {
}
func (suite *TypeUtilsTestSuite) SetupSuite() {
- suite.config = testrig.NewTestConfig()
- suite.db = testrig.NewTestDB()
testrig.InitTestLog()
+ testrig.InitTestConfig()
+
+ suite.db = testrig.NewTestDB()
suite.testAccounts = testrig.NewTestAccounts()
suite.testStatuses = testrig.NewTestStatuses()
suite.testPeople = testrig.NewTestFediPeople()
- suite.typeconverter = typeutils.NewConverter(suite.config, suite.db)
+ suite.typeconverter = typeutils.NewConverter(suite.db)
}
func (suite *TypeUtilsTestSuite) SetupTest() {
diff --git a/internal/typeutils/internal.go b/internal/typeutils/internal.go
index b6a425732..2257d7203 100644
--- a/internal/typeutils/internal.go
+++ b/internal/typeutils/internal.go
@@ -25,7 +25,7 @@ func (c *converter) FollowRequestToFollow(ctx context.Context, f *gtsmodel.Follo
func (c *converter) StatusToBoost(ctx context.Context, s *gtsmodel.Status, boostingAccount *gtsmodel.Account) (*gtsmodel.Status, error) {
// the wrapper won't use the same ID as the boosted status so we generate some new UUIDs
- uris := util.GenerateURIsForAccount(boostingAccount.Username, c.config.Protocol, c.config.Host)
+ uris := util.GenerateURIsForAccount(boostingAccount.Username)
boostWrapperStatusID, err := id.NewULID()
if err != nil {
return nil, err
diff --git a/internal/typeutils/internaltoas.go b/internal/typeutils/internaltoas.go
index ae8e3b1f2..1bf2416b8 100644
--- a/internal/typeutils/internaltoas.go
+++ b/internal/typeutils/internaltoas.go
@@ -25,9 +25,11 @@ import (
"fmt"
"net/url"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/activity/streams"
"github.com/superseriousbusiness/activity/streams/vocab"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
)
@@ -620,7 +622,8 @@ func (c *converter) MentionToAS(ctx context.Context, m *gtsmodel.Mention) (vocab
// name -- this should be the namestring of the mentioned user, something like @whatever@example.org
var domain string
if m.TargetAccount.Domain == "" {
- domain = c.config.AccountDomain
+ accountDomain := viper.GetString(config.Keys.AccountDomain)
+ domain = accountDomain
} else {
domain = m.TargetAccount.Domain
}
diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go
index 272ffc175..4dd8e335b 100644
--- a/internal/typeutils/internaltofrontend.go
+++ b/internal/typeutils/internaltofrontend.go
@@ -21,11 +21,14 @@ package typeutils
import (
"context"
"fmt"
- "github.com/sirupsen/logrus"
"strings"
"time"
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
+
"github.com/superseriousbusiness/gotosocial/internal/api/model"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
)
@@ -567,34 +570,32 @@ func (c *converter) InstanceToAPIInstance(ctx context.Context, i *gtsmodel.Insta
}
// if the requested instance is *this* instance, we can add some extra information
- if i.Domain == c.config.Host {
- userCountKey := "user_count"
- statusCountKey := "status_count"
- domainCountKey := "domain_count"
-
- userCount, err := c.db.CountInstanceUsers(ctx, c.config.Host)
+ keys := config.Keys
+ host := viper.GetString(keys.Host)
+ if i.Domain == host {
+ userCount, err := c.db.CountInstanceUsers(ctx, host)
if err == nil {
- mi.Stats[userCountKey] = userCount
+ mi.Stats["user_count"] = userCount
}
- statusCount, err := c.db.CountInstanceStatuses(ctx, c.config.Host)
+ statusCount, err := c.db.CountInstanceStatuses(ctx, host)
if err == nil {
- mi.Stats[statusCountKey] = statusCount
+ mi.Stats["status_count"] = statusCount
}
- domainCount, err := c.db.CountInstanceDomains(ctx, c.config.Host)
+ domainCount, err := c.db.CountInstanceDomains(ctx, host)
if err == nil {
- mi.Stats[domainCountKey] = domainCount
+ mi.Stats["domain_count"] = domainCount
}
- mi.Registrations = c.config.AccountsConfig.OpenRegistration
- mi.ApprovalRequired = c.config.AccountsConfig.RequireApproval
+ mi.Registrations = viper.GetBool(keys.AccountsRegistrationOpen)
+ mi.ApprovalRequired = viper.GetBool(keys.AccountsApprovalRequired)
mi.InvitesEnabled = false // TODO
- mi.MaxTootChars = uint(c.config.StatusesConfig.MaxChars)
+ mi.MaxTootChars = uint(viper.GetInt(keys.StatusesMaxChars))
mi.URLS = &model.InstanceURLs{
- StreamingAPI: fmt.Sprintf("wss://%s", c.config.Host),
+ StreamingAPI: fmt.Sprintf("wss://%s", host),
}
- mi.Version = c.config.SoftwareVersion
+ mi.Version = viper.GetString(keys.SoftwareVersion)
}
// get the instance account if it exists and just skip if it doesn't
diff --git a/internal/typeutils/wrap.go b/internal/typeutils/wrap.go
index b5938c419..0f82a679b 100644
--- a/internal/typeutils/wrap.go
+++ b/internal/typeutils/wrap.go
@@ -33,7 +33,7 @@ func (c *converter) WrapPersonInUpdate(person vocab.ActivityStreamsPerson, origi
return nil, err
}
- idString := util.GenerateURIForUpdate(originAccount.Username, c.config.Protocol, c.config.Host, newID)
+ idString := util.GenerateURIForUpdate(originAccount.Username, newID)
idURI, err := url.Parse(idString)
if err != nil {
return nil, fmt.Errorf("WrapPersonInUpdate: error parsing url %s: %s", idString, err)
diff --git a/internal/util/uri.go b/internal/util/uri.go
index d1ae1de41..b9ef01799 100644
--- a/internal/util/uri.go
+++ b/internal/util/uri.go
@@ -22,6 +22,8 @@ import (
"fmt"
"net/url"
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/regexes"
)
@@ -116,36 +118,49 @@ type UserURIs struct {
// GenerateURIForFollow returns the AP URI for a new follow -- something like:
// https://example.org/users/whatever_user/follow/01F7XTH1QGBAPMGF49WJZ91XGC
-func GenerateURIForFollow(username string, protocol string, host string, thisFollowID string) string {
+func GenerateURIForFollow(username string, thisFollowID string) string {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
return fmt.Sprintf("%s://%s/%s/%s/%s/%s", protocol, host, UsersPath, username, FollowPath, thisFollowID)
}
// GenerateURIForLike returns the AP URI for a new like/fave -- something like:
// https://example.org/users/whatever_user/liked/01F7XTH1QGBAPMGF49WJZ91XGC
-func GenerateURIForLike(username string, protocol string, host string, thisFavedID string) string {
+func GenerateURIForLike(username string, thisFavedID string) string {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
return fmt.Sprintf("%s://%s/%s/%s/%s/%s", protocol, host, UsersPath, username, LikedPath, thisFavedID)
}
// GenerateURIForUpdate returns the AP URI for a new update activity -- something like:
// https://example.org/users/whatever_user#updates/01F7XTH1QGBAPMGF49WJZ91XGC
-func GenerateURIForUpdate(username string, protocol string, host string, thisUpdateID string) string {
+func GenerateURIForUpdate(username string, thisUpdateID string) string {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
return fmt.Sprintf("%s://%s/%s/%s#%s/%s", protocol, host, UsersPath, username, UpdatePath, thisUpdateID)
}
// GenerateURIForBlock returns the AP URI for a new block activity -- something like:
// https://example.org/users/whatever_user/blocks/01F7XTH1QGBAPMGF49WJZ91XGC
-func GenerateURIForBlock(username string, protocol string, host string, thisBlockID string) string {
+func GenerateURIForBlock(username string, thisBlockID string) string {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
return fmt.Sprintf("%s://%s/%s/%s/%s/%s", protocol, host, UsersPath, username, BlocksPath, thisBlockID)
}
// GenerateURIForEmailConfirm returns a link for email confirmation -- something like:
// https://example.org/confirm_email?token=490e337c-0162-454f-ac48-4b22bb92a205
-func GenerateURIForEmailConfirm(protocol string, host string, token string) string {
+func GenerateURIForEmailConfirm(token string) string {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
return fmt.Sprintf("%s://%s/%s?token=%s", protocol, host, ConfirmEmailPath, token)
}
// GenerateURIsForAccount throws together a bunch of URIs for the given username, with the given protocol and host.
-func GenerateURIsForAccount(username string, protocol string, host string) *UserURIs {
+func GenerateURIsForAccount(username string) *UserURIs {
+ protocol := viper.GetString(config.Keys.Protocol)
+ host := viper.GetString(config.Keys.Host)
+
// The below URLs are used for serving web requests
hostURL := fmt.Sprintf("%s://%s", protocol, host)
userURL := fmt.Sprintf("%s/@%s", hostURL, username)
diff --git a/internal/visibility/filter_test.go b/internal/visibility/filter_test.go
index a140d48e2..12c1a72a6 100644
--- a/internal/visibility/filter_test.go
+++ b/internal/visibility/filter_test.go
@@ -20,7 +20,6 @@ package visibility_test
import (
"github.com/stretchr/testify/suite"
- "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/visibility"
@@ -30,8 +29,7 @@ import (
type FilterStandardTestSuite struct {
// standard suite interfaces
suite.Suite
- config *config.Config
- db db.DB
+ db db.DB
// standard suite models
testTokens map[string]*gtsmodel.Token
@@ -61,8 +59,8 @@ func (suite *FilterStandardTestSuite) SetupSuite() {
func (suite *FilterStandardTestSuite) SetupTest() {
testrig.InitTestLog()
+ testrig.InitTestConfig()
- suite.config = testrig.NewTestConfig()
suite.db = testrig.NewTestDB()
suite.filter = visibility.NewFilter(suite.db)
diff --git a/internal/web/base.go b/internal/web/base.go
index 5d19a3f70..9d99fddd1 100644
--- a/internal/web/base.go
+++ b/internal/web/base.go
@@ -26,6 +26,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
"github.com/superseriousbusiness/gotosocial/internal/api"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/processing"
@@ -40,14 +41,12 @@ const (
// Module implements the api.ClientModule interface for web pages.
type Module struct {
- config *config.Config
processor processing.Processor
}
// New returns a new api.ClientModule for web pages.
-func New(config *config.Config, processor processing.Processor) api.ClientModule {
+func New(processor processing.Processor) api.ClientModule {
return &Module{
- config: config,
processor: processor,
}
}
@@ -56,7 +55,8 @@ func (m *Module) baseHandler(c *gin.Context) {
l := logrus.WithField("func", "BaseGETHandler")
l.Trace("serving index html")
- 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"})
@@ -73,7 +73,8 @@ func (m *Module) NotFoundHandler(c *gin.Context) {
l := logrus.WithField("func", "404")
l.Trace("serving 404 html")
- 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"})
@@ -87,17 +88,17 @@ func (m *Module) NotFoundHandler(c *gin.Context) {
// Route satisfies the RESTAPIModule interface
func (m *Module) Route(s router.Router) error {
-
// serve static files from /assets
cwd, err := os.Getwd()
if err != nil {
return fmt.Errorf("error getting current working directory: %s", err)
}
- assetPath := filepath.Join(cwd, m.config.TemplateConfig.AssetBaseDir)
+ assetBaseDir := viper.GetString(config.Keys.WebAssetBaseDir)
+ assetPath := filepath.Join(cwd, assetBaseDir)
s.AttachStaticFS("/assets", fileSystem{http.Dir(assetPath)})
// Admin panel route, if it exists
- adminPath := filepath.Join(cwd, m.config.TemplateConfig.AssetBaseDir, "/admin")
+ adminPath := filepath.Join(cwd, assetBaseDir, "/admin")
s.AttachStaticFS("/admin", fileSystem{http.Dir(adminPath)})
// serve front-page
diff --git a/internal/web/confirmemail.go b/internal/web/confirmemail.go
index 97ed597d3..6eaa940c6 100644
--- a/internal/web/confirmemail.go
+++ b/internal/web/confirmemail.go
@@ -23,6 +23,8 @@ import (
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
)
func (m *Module) confirmEmailGETHandler(c *gin.Context) {
@@ -43,7 +45,8 @@ func (m *Module) confirmEmailGETHandler(c *gin.Context) {
return
}
- instance, err := m.processor.InstanceGet(ctx, m.config.Host)
+ host := viper.GetString(config.Keys.Host)
+ instance, err := m.processor.InstanceGet(ctx, host)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
diff --git a/internal/web/thread.go b/internal/web/thread.go
index a359107cc..578722674 100644
--- a/internal/web/thread.go
+++ b/internal/web/thread.go
@@ -19,10 +19,13 @@
package web
import (
- "github.com/sirupsen/logrus"
"net/http"
+ "github.com/sirupsen/logrus"
+ "github.com/spf13/viper"
+
"github.com/gin-gonic/gin"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
)
@@ -51,7 +54,8 @@ func (m *Module) threadTemplateHandler(c *gin.Context) {
return
}
- instance, err := m.processor.InstanceGet(ctx, m.config.Host)
+ host := viper.GetString(config.Keys.Host)
+ instance, err := m.processor.InstanceGet(ctx, host)
if err != nil {
l.Debugf("error getting instance from processor: %s", err)
c.JSON(http.StatusInternalServerError, gin.H{"error": "internal server error"})