forked from mirrors/gotosocial
[chore] Global server configuration overhaul (#575)
* move config flag names and usage to config package, rewrite config package to use global Configuration{} struct Signed-off-by: kim <grufwub@gmail.com> * improved code comment Signed-off-by: kim <grufwub@gmail.com> * linter Signed-off-by: kim <grufwub@gmail.com> * fix unmarshaling Signed-off-by: kim <grufwub@gmail.com> * remove kim's custom go compiler changes Signed-off-by: kim <grufwub@gmail.com> * generate setter and flag-name functions, implement these in codebase Signed-off-by: kim <grufwub@gmail.com> * update deps Signed-off-by: kim <grufwub@gmail.com> * small change Signed-off-by: kim <grufwub@gmail.com> * appease the linter... Signed-off-by: kim <grufwub@gmail.com> * move configuration into ConfigState structure, ensure reloading to/from viper settings to keep in sync Signed-off-by: kim <grufwub@gmail.com> * lint Signed-off-by: kim <grufwub@gmail.com> * update code comments Signed-off-by: kim <grufwub@gmail.com> * fix merge issue Signed-off-by: kim <grufwub@gmail.com> * fix merge issue Signed-off-by: kim <grufwub@gmail.com> * improved version string (removes time + go version) Signed-off-by: kim <grufwub@gmail.com> * fix version string build to pass test script + consolidate logic in func Signed-off-by: kim <grufwub@gmail.com> * add license text, update config.Defaults comment Signed-off-by: kim <grufwub@gmail.com> * add license text to generated config helpers file Signed-off-by: kim <grufwub@gmail.com> * defer unlock on config.Set___(), to ensure unlocked on panic Signed-off-by: kim <grufwub@gmail.com> * make it more obvious which cmd flags are being attached Signed-off-by: kim <grufwub@gmail.com>
This commit is contained in:
parent
ae5402ada6
commit
43ac0cdb9c
90 changed files with 2450 additions and 1125 deletions
|
@ -24,7 +24,6 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
|
@ -41,7 +40,7 @@ var Create action.GTSAction = func(ctx context.Context) error {
|
|||
return fmt.Errorf("error creating dbservice: %s", err)
|
||||
}
|
||||
|
||||
username := viper.GetString(config.Keys.AdminAccountUsername)
|
||||
username := config.GetAdminAccountUsername()
|
||||
if username == "" {
|
||||
return errors.New("no username set")
|
||||
}
|
||||
|
@ -49,7 +48,7 @@ var Create action.GTSAction = func(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
email := viper.GetString(config.Keys.AdminAccountEmail)
|
||||
email := config.GetAdminAccountEmail()
|
||||
if email == "" {
|
||||
return errors.New("no email set")
|
||||
}
|
||||
|
@ -57,7 +56,7 @@ var Create action.GTSAction = func(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
password := viper.GetString(config.Keys.AdminAccountPassword)
|
||||
password := config.GetAdminAccountPassword()
|
||||
if password == "" {
|
||||
return errors.New("no password set")
|
||||
}
|
||||
|
@ -80,7 +79,7 @@ var Confirm action.GTSAction = func(ctx context.Context) error {
|
|||
return fmt.Errorf("error creating dbservice: %s", err)
|
||||
}
|
||||
|
||||
username := viper.GetString(config.Keys.AdminAccountUsername)
|
||||
username := config.GetAdminAccountUsername()
|
||||
if username == "" {
|
||||
return errors.New("no username set")
|
||||
}
|
||||
|
@ -115,7 +114,7 @@ var Promote action.GTSAction = func(ctx context.Context) error {
|
|||
return fmt.Errorf("error creating dbservice: %s", err)
|
||||
}
|
||||
|
||||
username := viper.GetString(config.Keys.AdminAccountUsername)
|
||||
username := config.GetAdminAccountUsername()
|
||||
if username == "" {
|
||||
return errors.New("no username set")
|
||||
}
|
||||
|
@ -147,7 +146,7 @@ var Demote action.GTSAction = func(ctx context.Context) error {
|
|||
return fmt.Errorf("error creating dbservice: %s", err)
|
||||
}
|
||||
|
||||
username := viper.GetString(config.Keys.AdminAccountUsername)
|
||||
username := config.GetAdminAccountUsername()
|
||||
if username == "" {
|
||||
return errors.New("no username set")
|
||||
}
|
||||
|
@ -179,7 +178,7 @@ var Disable action.GTSAction = func(ctx context.Context) error {
|
|||
return fmt.Errorf("error creating dbservice: %s", err)
|
||||
}
|
||||
|
||||
username := viper.GetString(config.Keys.AdminAccountUsername)
|
||||
username := config.GetAdminAccountUsername()
|
||||
if username == "" {
|
||||
return errors.New("no username set")
|
||||
}
|
||||
|
@ -217,7 +216,7 @@ var Password action.GTSAction = func(ctx context.Context) error {
|
|||
return fmt.Errorf("error creating dbservice: %s", err)
|
||||
}
|
||||
|
||||
username := viper.GetString(config.Keys.AdminAccountUsername)
|
||||
username := config.GetAdminAccountUsername()
|
||||
if username == "" {
|
||||
return errors.New("no username set")
|
||||
}
|
||||
|
@ -225,7 +224,7 @@ var Password action.GTSAction = func(ctx context.Context) error {
|
|||
return err
|
||||
}
|
||||
|
||||
password := viper.GetString(config.Keys.AdminAccountPassword)
|
||||
password := config.GetAdminAccountPassword()
|
||||
if password == "" {
|
||||
return errors.New("no password set")
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db/bundb"
|
||||
|
@ -39,7 +38,7 @@ var Export action.GTSAction = func(ctx context.Context) error {
|
|||
|
||||
exporter := trans.NewExporter(dbConn)
|
||||
|
||||
path := viper.GetString(config.Keys.AdminTransPath)
|
||||
path := config.GetAdminTransPath()
|
||||
if path == "" {
|
||||
return errors.New("no path set")
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db/bundb"
|
||||
|
@ -39,7 +38,7 @@ var Import action.GTSAction = func(ctx context.Context) error {
|
|||
|
||||
importer := trans.NewImporter(dbConn)
|
||||
|
||||
path := viper.GetString(config.Keys.AdminTransPath)
|
||||
path := config.GetAdminTransPath()
|
||||
if path == "" {
|
||||
return errors.New("no path set")
|
||||
}
|
||||
|
|
|
@ -23,17 +23,29 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
// Config just prints the collated config out to stdout as json.
|
||||
var Config action.GTSAction = func(ctx context.Context) error {
|
||||
allSettings := viper.AllSettings()
|
||||
b, err := json.Marshal(&allSettings)
|
||||
var Config action.GTSAction = func(ctx context.Context) (err error) {
|
||||
var raw map[string]interface{}
|
||||
|
||||
// Marshal configuration to a raw JSON map
|
||||
config.Config(func(cfg *config.Configuration) {
|
||||
raw, err = cfg.MarshalMap()
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println(string(b))
|
||||
|
||||
// Marshal map to JSON
|
||||
b, err := json.Marshal(raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Print to stdout
|
||||
fmt.Printf("%s\n", b)
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@ import (
|
|||
"codeberg.org/gruf/go-store/kv"
|
||||
"codeberg.org/gruf/go-store/storage"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/client/account"
|
||||
|
@ -107,7 +106,7 @@ var Start action.GTSAction = func(ctx context.Context) error {
|
|||
typeConverter := typeutils.NewConverter(dbService)
|
||||
|
||||
// Open the storage backend
|
||||
storageBasePath := viper.GetString(config.Keys.StorageLocalBasePath)
|
||||
storageBasePath := config.GetStorageLocalBasePath()
|
||||
storage, err := kv.OpenFile(storageBasePath, &storage.DiskConfig{
|
||||
// Put the store lockfile in the storage dir itself.
|
||||
// Normally this would not be safe, since we could end up
|
||||
|
@ -134,8 +133,7 @@ var Start action.GTSAction = func(ctx context.Context) error {
|
|||
|
||||
// decide whether to create a noop email sender (won't send emails) or a real one
|
||||
var emailSender email.Sender
|
||||
smtpHost := viper.GetString(config.Keys.SMTPHost)
|
||||
if smtpHost != "" {
|
||||
if smtpHost := config.GetSMTPHost(); smtpHost != "" {
|
||||
// host is defined so create a proper sender
|
||||
emailSender, err = email.NewSender()
|
||||
if err != nil {
|
||||
|
@ -239,7 +237,7 @@ var Start action.GTSAction = func(ctx context.Context) error {
|
|||
}
|
||||
|
||||
// perform initial media prune in case value of MediaRemoteCacheDays changed
|
||||
if err := processor.AdminMediaPrune(ctx, viper.GetInt(config.Keys.MediaRemoteCacheDays)); err != nil {
|
||||
if err := processor.AdminMediaPrune(ctx, config.GetMediaRemoteCacheDays()); err != nil {
|
||||
return fmt.Errorf("error during initial media prune: %s", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action/admin/account"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action/admin/trans"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/flag"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
|
@ -40,7 +39,7 @@ func adminCommands() *cobra.Command {
|
|||
Use: "account",
|
||||
Short: "admin commands related to accounts",
|
||||
}
|
||||
flag.AdminAccount(adminAccountCmd, config.Defaults)
|
||||
config.AddAdminAccount(adminAccountCmd)
|
||||
|
||||
adminAccountCreateCmd := &cobra.Command{
|
||||
Use: "create",
|
||||
|
@ -52,7 +51,7 @@ func adminCommands() *cobra.Command {
|
|||
return run(cmd.Context(), account.Create)
|
||||
},
|
||||
}
|
||||
flag.AdminAccountCreate(adminAccountCreateCmd, config.Defaults)
|
||||
config.AddAdminAccountCreate(adminAccountCreateCmd)
|
||||
adminAccountCmd.AddCommand(adminAccountCreateCmd)
|
||||
|
||||
adminAccountConfirmCmd := &cobra.Command{
|
||||
|
@ -65,7 +64,7 @@ func adminCommands() *cobra.Command {
|
|||
return run(cmd.Context(), account.Confirm)
|
||||
},
|
||||
}
|
||||
flag.AdminAccount(adminAccountConfirmCmd, config.Defaults)
|
||||
config.AddAdminAccount(adminAccountConfirmCmd)
|
||||
adminAccountCmd.AddCommand(adminAccountConfirmCmd)
|
||||
|
||||
adminAccountPromoteCmd := &cobra.Command{
|
||||
|
@ -78,7 +77,7 @@ func adminCommands() *cobra.Command {
|
|||
return run(cmd.Context(), account.Promote)
|
||||
},
|
||||
}
|
||||
flag.AdminAccount(adminAccountPromoteCmd, config.Defaults)
|
||||
config.AddAdminAccount(adminAccountPromoteCmd)
|
||||
adminAccountCmd.AddCommand(adminAccountPromoteCmd)
|
||||
|
||||
adminAccountDemoteCmd := &cobra.Command{
|
||||
|
@ -91,7 +90,7 @@ func adminCommands() *cobra.Command {
|
|||
return run(cmd.Context(), account.Demote)
|
||||
},
|
||||
}
|
||||
flag.AdminAccount(adminAccountDemoteCmd, config.Defaults)
|
||||
config.AddAdminAccount(adminAccountDemoteCmd)
|
||||
adminAccountCmd.AddCommand(adminAccountDemoteCmd)
|
||||
|
||||
adminAccountDisableCmd := &cobra.Command{
|
||||
|
@ -104,7 +103,7 @@ func adminCommands() *cobra.Command {
|
|||
return run(cmd.Context(), account.Disable)
|
||||
},
|
||||
}
|
||||
flag.AdminAccount(adminAccountDisableCmd, config.Defaults)
|
||||
config.AddAdminAccount(adminAccountDisableCmd)
|
||||
adminAccountCmd.AddCommand(adminAccountDisableCmd)
|
||||
|
||||
adminAccountSuspendCmd := &cobra.Command{
|
||||
|
@ -117,7 +116,7 @@ func adminCommands() *cobra.Command {
|
|||
return run(cmd.Context(), account.Suspend)
|
||||
},
|
||||
}
|
||||
flag.AdminAccount(adminAccountSuspendCmd, config.Defaults)
|
||||
config.AddAdminAccount(adminAccountSuspendCmd)
|
||||
adminAccountCmd.AddCommand(adminAccountSuspendCmd)
|
||||
|
||||
adminAccountPasswordCmd := &cobra.Command{
|
||||
|
@ -130,7 +129,8 @@ func adminCommands() *cobra.Command {
|
|||
return run(cmd.Context(), account.Password)
|
||||
},
|
||||
}
|
||||
flag.AdminAccountPassword(adminAccountPasswordCmd, config.Defaults)
|
||||
config.AddAdminAccount(adminAccountPasswordCmd)
|
||||
config.AddAdminAccountPassword(adminAccountPasswordCmd)
|
||||
adminAccountCmd.AddCommand(adminAccountPasswordCmd)
|
||||
|
||||
adminCmd.AddCommand(adminAccountCmd)
|
||||
|
@ -149,7 +149,7 @@ func adminCommands() *cobra.Command {
|
|||
return run(cmd.Context(), trans.Export)
|
||||
},
|
||||
}
|
||||
flag.AdminTrans(adminExportCmd, config.Defaults)
|
||||
config.AddAdminTrans(adminExportCmd)
|
||||
adminCmd.AddCommand(adminExportCmd)
|
||||
|
||||
adminImportCmd := &cobra.Command{
|
||||
|
@ -162,7 +162,7 @@ func adminCommands() *cobra.Command {
|
|||
return run(cmd.Context(), trans.Import)
|
||||
},
|
||||
}
|
||||
flag.AdminTrans(adminImportCmd, config.Defaults)
|
||||
config.AddAdminTrans(adminImportCmd)
|
||||
adminCmd.AddCommand(adminImportCmd)
|
||||
|
||||
return adminCmd
|
||||
|
|
|
@ -43,12 +43,12 @@ type preRunArgs struct {
|
|||
// of the config file from the viper store so that it can be picked up by either
|
||||
// env vars or cli flag.
|
||||
func preRun(a preRunArgs) error {
|
||||
if err := config.InitViper(a.cmd.Flags()); err != nil {
|
||||
return fmt.Errorf("error initializing viper: %s", err)
|
||||
if err := config.BindFlags(a.cmd); err != nil {
|
||||
return fmt.Errorf("error binding flags: %s", err)
|
||||
}
|
||||
|
||||
if err := config.ReadFromFile(); err != nil {
|
||||
return fmt.Errorf("error initializing config: %s", err)
|
||||
if err := config.Reload(); err != nil {
|
||||
return fmt.Errorf("error reloading config: %s", err)
|
||||
}
|
||||
|
||||
if !a.skipValidation {
|
||||
|
|
|
@ -21,7 +21,6 @@ package main
|
|||
import (
|
||||
"github.com/spf13/cobra"
|
||||
configaction "github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action/debug/config"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/flag"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
|
@ -41,8 +40,7 @@ func debugCommands() *cobra.Command {
|
|||
return run(cmd.Context(), configaction.Config)
|
||||
},
|
||||
}
|
||||
flag.Server(debugConfigCmd, config.Defaults)
|
||||
|
||||
config.AddServerFlags(debugConfigCmd)
|
||||
debugCmd.AddCommand(debugConfigCmd)
|
||||
return debugCmd
|
||||
}
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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 flag
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
// AdminAccount attaches flags pertaining to admin account actions.
|
||||
func AdminAccount(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().String(config.Keys.AdminAccountUsername, "", usage.AdminAccountUsername) // REQUIRED
|
||||
if err := cmd.MarkFlagRequired(config.Keys.AdminAccountUsername); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// AdminAccountPassword attaches flags pertaining to admin account password reset.
|
||||
func AdminAccountPassword(cmd *cobra.Command, values config.Values) {
|
||||
AdminAccount(cmd, values)
|
||||
cmd.Flags().String(config.Keys.AdminAccountPassword, "", usage.AdminAccountPassword) // REQUIRED
|
||||
if err := cmd.MarkFlagRequired(config.Keys.AdminAccountPassword); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// AdminAccountCreate attaches flags pertaining to admin account creation.
|
||||
func AdminAccountCreate(cmd *cobra.Command, values config.Values) {
|
||||
AdminAccount(cmd, values)
|
||||
cmd.Flags().String(config.Keys.AdminAccountPassword, "", usage.AdminAccountPassword) // REQUIRED
|
||||
if err := cmd.MarkFlagRequired(config.Keys.AdminAccountPassword); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
cmd.Flags().String(config.Keys.AdminAccountEmail, "", usage.AdminAccountEmail) // REQUIRED
|
||||
if err := cmd.MarkFlagRequired(config.Keys.AdminAccountEmail); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// AdminTrans attaches flags pertaining to import/export commands.
|
||||
func AdminTrans(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().String(config.Keys.AdminTransPath, "", usage.AdminTransPath) // REQUIRED
|
||||
if err := cmd.MarkFlagRequired(config.Keys.AdminTransPath); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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 flag
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
// Global attaches flags that are common to all commands, aka persistent commands.
|
||||
func Global(cmd *cobra.Command, values config.Values) {
|
||||
// general stuff
|
||||
cmd.PersistentFlags().String(config.Keys.ApplicationName, values.ApplicationName, usage.ApplicationName)
|
||||
cmd.PersistentFlags().String(config.Keys.Host, values.Host, usage.Host)
|
||||
cmd.PersistentFlags().String(config.Keys.AccountDomain, values.AccountDomain, usage.AccountDomain)
|
||||
cmd.PersistentFlags().String(config.Keys.Protocol, values.Protocol, usage.Protocol)
|
||||
cmd.PersistentFlags().String(config.Keys.LogLevel, values.LogLevel, usage.LogLevel)
|
||||
cmd.PersistentFlags().Bool(config.Keys.LogDbQueries, values.LogDbQueries, usage.LogDbQueries)
|
||||
cmd.PersistentFlags().String(config.Keys.ConfigPath, values.ConfigPath, usage.ConfigPath)
|
||||
|
||||
// database stuff
|
||||
cmd.PersistentFlags().String(config.Keys.DbType, values.DbType, usage.DbType)
|
||||
cmd.PersistentFlags().String(config.Keys.DbAddress, values.DbAddress, usage.DbAddress)
|
||||
cmd.PersistentFlags().Int(config.Keys.DbPort, values.DbPort, usage.DbPort)
|
||||
cmd.PersistentFlags().String(config.Keys.DbUser, values.DbUser, usage.DbUser)
|
||||
cmd.PersistentFlags().String(config.Keys.DbPassword, values.DbPassword, usage.DbPassword)
|
||||
cmd.PersistentFlags().String(config.Keys.DbDatabase, values.DbDatabase, usage.DbDatabase)
|
||||
cmd.PersistentFlags().String(config.Keys.DbTLSMode, values.DbTLSMode, usage.DbTLSMode)
|
||||
cmd.PersistentFlags().String(config.Keys.DbTLSCACert, values.DbTLSCACert, usage.DbTLSCACert)
|
||||
}
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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 flag
|
||||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
// Server attaches all flags pertaining to running the GtS server or testrig.
|
||||
func Server(cmd *cobra.Command, values config.Values) {
|
||||
Template(cmd, values)
|
||||
Accounts(cmd, values)
|
||||
Media(cmd, values)
|
||||
Storage(cmd, values)
|
||||
Statuses(cmd, values)
|
||||
LetsEncrypt(cmd, values)
|
||||
OIDC(cmd, values)
|
||||
SMTP(cmd, values)
|
||||
Router(cmd, values)
|
||||
Syslog(cmd, values)
|
||||
}
|
||||
|
||||
// Router attaches flags pertaining to the gin router.
|
||||
func Router(cmd *cobra.Command, values config.Values) {
|
||||
cmd.PersistentFlags().String(config.Keys.BindAddress, values.BindAddress, usage.BindAddress)
|
||||
cmd.PersistentFlags().Int(config.Keys.Port, values.Port, usage.Port)
|
||||
cmd.PersistentFlags().StringSlice(config.Keys.TrustedProxies, values.TrustedProxies, usage.TrustedProxies)
|
||||
}
|
||||
|
||||
// Template attaches flags pertaining to templating config.
|
||||
func Template(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().String(config.Keys.WebTemplateBaseDir, values.WebTemplateBaseDir, usage.WebTemplateBaseDir)
|
||||
cmd.Flags().String(config.Keys.WebAssetBaseDir, values.WebAssetBaseDir, usage.WebAssetBaseDir)
|
||||
}
|
||||
|
||||
// Accounts attaches flags pertaining to account config.
|
||||
func Accounts(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().Bool(config.Keys.AccountsRegistrationOpen, values.AccountsRegistrationOpen, usage.AccountsRegistrationOpen)
|
||||
cmd.Flags().Bool(config.Keys.AccountsApprovalRequired, values.AccountsApprovalRequired, usage.AccountsApprovalRequired)
|
||||
cmd.Flags().Bool(config.Keys.AccountsReasonRequired, values.AccountsReasonRequired, usage.AccountsReasonRequired)
|
||||
}
|
||||
|
||||
// Media attaches flags pertaining to media config.
|
||||
func Media(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().Int(config.Keys.MediaImageMaxSize, values.MediaImageMaxSize, usage.MediaImageMaxSize)
|
||||
cmd.Flags().Int(config.Keys.MediaVideoMaxSize, values.MediaVideoMaxSize, usage.MediaVideoMaxSize)
|
||||
cmd.Flags().Int(config.Keys.MediaDescriptionMinChars, values.MediaDescriptionMinChars, usage.MediaDescriptionMinChars)
|
||||
cmd.Flags().Int(config.Keys.MediaDescriptionMaxChars, values.MediaDescriptionMaxChars, usage.MediaDescriptionMaxChars)
|
||||
cmd.Flags().Int(config.Keys.MediaRemoteCacheDays, values.MediaRemoteCacheDays, usage.MediaRemoteCacheDays)
|
||||
}
|
||||
|
||||
// Storage attaches flags pertaining to storage config.
|
||||
func Storage(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().String(config.Keys.StorageBackend, values.StorageBackend, usage.StorageBackend)
|
||||
cmd.Flags().String(config.Keys.StorageLocalBasePath, values.StorageLocalBasePath, usage.StorageLocalBasePath)
|
||||
}
|
||||
|
||||
// Statuses attaches flags pertaining to statuses config.
|
||||
func Statuses(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().Int(config.Keys.StatusesMaxChars, values.StatusesMaxChars, usage.StatusesMaxChars)
|
||||
cmd.Flags().Int(config.Keys.StatusesCWMaxChars, values.StatusesCWMaxChars, usage.StatusesCWMaxChars)
|
||||
cmd.Flags().Int(config.Keys.StatusesPollMaxOptions, values.StatusesPollMaxOptions, usage.StatusesPollMaxOptions)
|
||||
cmd.Flags().Int(config.Keys.StatusesPollOptionMaxChars, values.StatusesPollOptionMaxChars, usage.StatusesPollOptionMaxChars)
|
||||
cmd.Flags().Int(config.Keys.StatusesMediaMaxFiles, values.StatusesMediaMaxFiles, usage.StatusesMediaMaxFiles)
|
||||
}
|
||||
|
||||
// LetsEncrypt attaches flags pertaining to letsencrypt config.
|
||||
func LetsEncrypt(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().Bool(config.Keys.LetsEncryptEnabled, values.LetsEncryptEnabled, usage.LetsEncryptEnabled)
|
||||
cmd.Flags().Int(config.Keys.LetsEncryptPort, values.LetsEncryptPort, usage.LetsEncryptPort)
|
||||
cmd.Flags().String(config.Keys.LetsEncryptCertDir, values.LetsEncryptCertDir, usage.LetsEncryptCertDir)
|
||||
cmd.Flags().String(config.Keys.LetsEncryptEmailAddress, values.LetsEncryptEmailAddress, usage.LetsEncryptEmailAddress)
|
||||
}
|
||||
|
||||
// OIDC attaches flags pertaining to oidc config.
|
||||
func OIDC(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().Bool(config.Keys.OIDCEnabled, values.OIDCEnabled, usage.OIDCEnabled)
|
||||
cmd.Flags().String(config.Keys.OIDCIdpName, values.OIDCIdpName, usage.OIDCIdpName)
|
||||
cmd.Flags().Bool(config.Keys.OIDCSkipVerification, values.OIDCSkipVerification, usage.OIDCSkipVerification)
|
||||
cmd.Flags().String(config.Keys.OIDCIssuer, values.OIDCIssuer, usage.OIDCIssuer)
|
||||
cmd.Flags().String(config.Keys.OIDCClientID, values.OIDCClientID, usage.OIDCClientID)
|
||||
cmd.Flags().String(config.Keys.OIDCClientSecret, values.OIDCClientSecret, usage.OIDCClientSecret)
|
||||
cmd.Flags().StringSlice(config.Keys.OIDCScopes, values.OIDCScopes, usage.OIDCScopes)
|
||||
}
|
||||
|
||||
// SMTP attaches flags pertaining to smtp/email config.
|
||||
func SMTP(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().String(config.Keys.SMTPHost, values.SMTPHost, usage.SMTPHost)
|
||||
cmd.Flags().Int(config.Keys.SMTPPort, values.SMTPPort, usage.SMTPPort)
|
||||
cmd.Flags().String(config.Keys.SMTPUsername, values.SMTPUsername, usage.SMTPUsername)
|
||||
cmd.Flags().String(config.Keys.SMTPPassword, values.SMTPPassword, usage.SMTPPassword)
|
||||
cmd.Flags().String(config.Keys.SMTPFrom, values.SMTPFrom, usage.SMTPFrom)
|
||||
}
|
||||
|
||||
// Syslog attaches flags pertaining to syslog config.
|
||||
func Syslog(cmd *cobra.Command, values config.Values) {
|
||||
cmd.Flags().Bool(config.Keys.SyslogEnabled, values.SyslogEnabled, usage.SyslogEnabled)
|
||||
cmd.Flags().String(config.Keys.SyslogProtocol, values.SyslogProtocol, usage.SyslogProtocol)
|
||||
cmd.Flags().String(config.Keys.SyslogAddress, values.SyslogAddress, usage.SyslogAddress)
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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 flag
|
||||
|
||||
import "github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
||||
var usage = config.KeyNames{
|
||||
LogLevel: "Log level to run at: [trace, debug, info, warn, fatal]",
|
||||
LogDbQueries: "Log database queries verbosely when log-level is trace or debug",
|
||||
ApplicationName: "Name of the application, used in various places internally",
|
||||
ConfigPath: "Path to a file containing gotosocial configuration. Values set in this file will be overwritten by values set as env vars or arguments",
|
||||
Host: "Hostname to use for the server (eg., example.org, gotosocial.whatever.com). This value must be set. DO NOT change this on a server that's already run!",
|
||||
AccountDomain: "Domain to use in account names (eg., example.org, whatever.com). If not set, will default to the setting for host. DO NOT change this on a server that's already run!",
|
||||
Protocol: "Protocol to use for the REST api of the server. This value must be set to one of http or https; only use http for debugging and tests!",
|
||||
BindAddress: "Bind address to use for the GoToSocial server (eg., 0.0.0.0, 172.138.0.9, [::], localhost). For ipv6, enclose the address in square brackets, eg [2001:db8::fed1]. Default binds to all interfaces.",
|
||||
Port: "Port to use for GoToSocial. Change this to 443 if you're running the binary directly on the host machine.",
|
||||
TrustedProxies: "Proxies to trust when parsing x-forwarded headers into real IPs.",
|
||||
DbType: "Database type: eg., postgres",
|
||||
DbAddress: "Database ipv4 address, hostname, or filename",
|
||||
DbPort: "Database port",
|
||||
DbUser: "Database username",
|
||||
DbPassword: "Database password",
|
||||
DbDatabase: "Database name",
|
||||
DbTLSMode: "Database tls mode",
|
||||
DbTLSCACert: "Path to CA cert for db tls connection",
|
||||
WebTemplateBaseDir: "Basedir for html templating files for rendering pages and composing emails.",
|
||||
WebAssetBaseDir: "Directory to serve static assets from, accessible at example.org/assets/",
|
||||
AccountsRegistrationOpen: "Allow anyone to submit an account signup request. If false, server will be invite-only.",
|
||||
AccountsApprovalRequired: "Do account signups require approval by an admin or moderator before user can log in? If false, new registrations will be automatically approved.",
|
||||
AccountsReasonRequired: "Do new account signups require a reason to be submitted on registration?",
|
||||
MediaImageMaxSize: "Max size of accepted images in bytes",
|
||||
MediaVideoMaxSize: "Max size of accepted videos in bytes",
|
||||
MediaDescriptionMinChars: "Min required chars for an image description",
|
||||
MediaDescriptionMaxChars: "Max permitted chars for an image description",
|
||||
MediaRemoteCacheDays: "Number of days to locally cache media from remote instances. If set to 0, remote media will be kept indefinitely.",
|
||||
StorageBackend: "Storage backend to use for media attachments",
|
||||
StorageLocalBasePath: "Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir.",
|
||||
StatusesMaxChars: "Max permitted characters for posted statuses",
|
||||
StatusesCWMaxChars: "Max permitted characters for content/spoiler warnings on statuses",
|
||||
StatusesPollMaxOptions: "Max amount of options permitted on a poll",
|
||||
StatusesPollOptionMaxChars: "Max amount of characters for a poll option",
|
||||
StatusesMediaMaxFiles: "Maximum number of media files/attachments per status",
|
||||
LetsEncryptEnabled: "Enable letsencrypt TLS certs for this server. If set to true, then cert dir also needs to be set (or take the default).",
|
||||
LetsEncryptPort: "Port to listen on for letsencrypt certificate challenges. Must not be the same as the GtS webserver/API port.",
|
||||
LetsEncryptCertDir: "Directory to store acquired letsencrypt certificates.",
|
||||
LetsEncryptEmailAddress: "Email address to use when requesting letsencrypt certs. Will receive updates on cert expiry etc.",
|
||||
OIDCEnabled: "Enabled OIDC authorization for this instance. If set to true, then the other OIDC flags must also be set.",
|
||||
OIDCIdpName: "Name of the OIDC identity provider. Will be shown to the user when logging in.",
|
||||
OIDCSkipVerification: "Skip verification of tokens returned by the OIDC provider. Should only be set to 'true' for testing purposes, never in a production environment!",
|
||||
OIDCIssuer: "Address of the OIDC issuer. Should be the web address, including protocol, at which the issuer can be reached. Eg., 'https://example.org/auth'",
|
||||
OIDCClientID: "ClientID of GoToSocial, as registered with the OIDC provider.",
|
||||
OIDCClientSecret: "ClientSecret of GoToSocial, as registered with the OIDC provider.",
|
||||
OIDCScopes: "OIDC scopes.",
|
||||
SMTPHost: "Host of the smtp server. Eg., 'smtp.eu.mailgun.org'",
|
||||
SMTPPort: "Port of the smtp server. Eg., 587",
|
||||
SMTPUsername: "Username to authenticate with the smtp server as. Eg., 'postmaster@mail.example.org'",
|
||||
SMTPPassword: "Password to pass to the smtp server.",
|
||||
SMTPFrom: "Address to use as the 'from' field of the email. Eg., 'gotosocial@example.org'",
|
||||
SyslogEnabled: "Enable the syslog logging hook. Logs will be mirrored to the configured destination.",
|
||||
SyslogProtocol: "Protocol to use when directing logs to syslog. Leave empty to connect to local syslog.",
|
||||
SyslogAddress: "Address:port to send syslog logs to. Leave empty to connect to local syslog.",
|
||||
AdminAccountUsername: "the username to create/delete/etc",
|
||||
AdminAccountEmail: "the email address of this account",
|
||||
AdminAccountPassword: "the password to set for this account",
|
||||
AdminTransPath: "the path of the file to import from/export to",
|
||||
}
|
|
@ -19,14 +19,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/flag"
|
||||
_ "github.com/superseriousbusiness/gotosocial/docs"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
@ -37,48 +35,28 @@ var Version string
|
|||
|
||||
//go:generate swagger generate spec
|
||||
func main() {
|
||||
buildInfo, ok := debug.ReadBuildInfo()
|
||||
if !ok {
|
||||
panic("could not read buildinfo")
|
||||
}
|
||||
// Load version string
|
||||
version := version()
|
||||
|
||||
goVersion := buildInfo.GoVersion
|
||||
var commit string
|
||||
var time string
|
||||
for _, s := range buildInfo.Settings {
|
||||
if s.Key == "vcs.revision" {
|
||||
commit = s.Value[:7]
|
||||
}
|
||||
if s.Key == "vcs.time" {
|
||||
time = s.Value
|
||||
}
|
||||
}
|
||||
|
||||
var versionString string
|
||||
if Version != "" {
|
||||
versionString = fmt.Sprintf("%s %s %s [%s]", Version, commit, time, goVersion)
|
||||
}
|
||||
|
||||
// override software version in viper store
|
||||
viper.Set(config.Keys.SoftwareVersion, versionString)
|
||||
// override version in config store
|
||||
config.SetSoftwareVersion(version)
|
||||
|
||||
// instantiate the root command
|
||||
rootCmd := &cobra.Command{
|
||||
Use: "gotosocial",
|
||||
Short: "GoToSocial - a fediverse social media server",
|
||||
Long: "GoToSocial - a fediverse social media server\n\nFor help, see: https://docs.gotosocial.org.\n\nCode: https://github.com/superseriousbusiness/gotosocial",
|
||||
Version: versionString,
|
||||
Version: version,
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
// before running any other cmd funcs, we must load config-path
|
||||
return config.LoadEarlyFlags(cmd)
|
||||
},
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
}
|
||||
|
||||
// attach global flags to the root command so that they can be accessed from any subcommand
|
||||
flag.Global(rootCmd, config.Defaults)
|
||||
|
||||
// bind the config-path flag to viper early so that we can call it in the pre-run of following commands
|
||||
if err := viper.BindPFlag(config.Keys.ConfigPath, rootCmd.PersistentFlags().Lookup(config.Keys.ConfigPath)); err != nil {
|
||||
logrus.Fatalf("error attaching config flag: %s", err)
|
||||
}
|
||||
config.AddGlobalFlags(rootCmd)
|
||||
|
||||
// add subcommands
|
||||
rootCmd.AddCommand(serverCommands())
|
||||
|
@ -91,3 +69,45 @@ func main() {
|
|||
logrus.Fatalf("error executing command: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// version will build a version string from binary's stored build information.
|
||||
func version() string {
|
||||
// Read build information from binary
|
||||
build, ok := debug.ReadBuildInfo()
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Define easy getter to fetch build settings
|
||||
getSetting := func(key string) string {
|
||||
for i := 0; i < len(build.Settings); i++ {
|
||||
if build.Settings[i].Key == key {
|
||||
return build.Settings[i].Value
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var info []string
|
||||
|
||||
if Version != "" {
|
||||
// Append version if set
|
||||
info = append(info, Version)
|
||||
}
|
||||
|
||||
if vcs := getSetting("vcs"); vcs != "" {
|
||||
// A VCS type was set (99.9% probably git)
|
||||
|
||||
if commit := getSetting("vcs.revision"); commit != "" {
|
||||
if len(commit) > 7 {
|
||||
// Truncate commit
|
||||
commit = commit[:7]
|
||||
}
|
||||
|
||||
// Append VCS + commit if set
|
||||
info = append(info, vcs+"-"+commit)
|
||||
}
|
||||
}
|
||||
|
||||
return strings.Join(info, " ")
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ package main
|
|||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action/server"
|
||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/flag"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
|
@ -31,7 +30,6 @@ func serverCommands() *cobra.Command {
|
|||
Use: "server",
|
||||
Short: "gotosocial server-related tasks",
|
||||
}
|
||||
|
||||
serverStartCmd := &cobra.Command{
|
||||
Use: "start",
|
||||
Short: "start the gotosocial server",
|
||||
|
@ -42,8 +40,7 @@ func serverCommands() *cobra.Command {
|
|||
return run(cmd.Context(), server.Start)
|
||||
},
|
||||
}
|
||||
flag.Server(serverStartCmd, config.Defaults)
|
||||
|
||||
config.AddServerFlags(serverStartCmd)
|
||||
serverCmd.AddCommand(serverStartCmd)
|
||||
return serverCmd
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -32,7 +32,6 @@ require (
|
|||
github.com/russross/blackfriday/v2 v2.1.0
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/spf13/cobra v1.4.0
|
||||
github.com/spf13/pflag v1.0.5
|
||||
github.com/spf13/viper v1.11.0
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/superseriousbusiness/activity v1.1.0-gts
|
||||
|
@ -105,6 +104,7 @@ require (
|
|||
github.com/spf13/afero v1.8.2 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe // indirect
|
||||
github.com/tdewolff/parse/v2 v2.5.29 // indirect
|
||||
|
|
|
@ -8,7 +8,6 @@ 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/concurrency"
|
||||
|
@ -90,8 +89,8 @@ func (suite *AccountStandardTestSuite) newContext(recorder *httptest.ResponseRec
|
|||
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
|
||||
ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"])
|
||||
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
baseURI := fmt.Sprintf("%s://%s", protocol, host)
|
||||
requestURI := fmt.Sprintf("%s/%s", baseURI, requestPath)
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
|
@ -123,9 +122,7 @@ 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) error {
|
||||
keys := config.Keys
|
||||
|
||||
if !viper.GetBool(keys.AccountsRegistrationOpen) {
|
||||
if !config.GetAccountsRegistrationOpen() {
|
||||
return errors.New("registration is not open for this server")
|
||||
}
|
||||
|
||||
|
@ -149,7 +146,7 @@ func validateCreateAccount(form *model.AccountCreateRequest) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := validate.SignUpReason(form.Reason, viper.GetBool(keys.AccountsReasonRequired)); err != nil {
|
||||
if err := validate.SignUpReason(form.Reason, config.GetAccountsReasonRequired()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ 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/admin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/concurrency"
|
||||
|
@ -108,8 +107,8 @@ func (suite *AdminStandardTestSuite) newContext(recorder *httptest.ResponseRecor
|
|||
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["admin_account"])
|
||||
ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["admin_account"])
|
||||
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
baseURI := fmt.Sprintf("%s://%s", protocol, host)
|
||||
requestURI := fmt.Sprintf("%s/%s", baseURI, requestPath)
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
|
||||
"github.com/gin-gonic/gin"
|
||||
"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/oauth"
|
||||
|
@ -93,7 +92,7 @@ func (m *Module) MediaCleanupPOSTHandler(c *gin.Context) {
|
|||
|
||||
var remoteCacheDays int
|
||||
if form.RemoteCacheDays == nil {
|
||||
remoteCacheDays = viper.GetInt(config.Keys.MediaRemoteCacheDays)
|
||||
remoteCacheDays = config.GetMediaRemoteCacheDays()
|
||||
} else {
|
||||
remoteCacheDays = *form.RemoteCacheDays
|
||||
}
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/sessions/memstore"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/client/auth"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
@ -96,8 +95,8 @@ func (suite *AuthStandardTestSuite) newContext(requestMethod string, requestPath
|
|||
testrig.ConfigureTemplatesWithGin(engine)
|
||||
|
||||
// create the request
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
baseURI := fmt.Sprintf("%s://%s", protocol, host)
|
||||
requestURI := fmt.Sprintf("%s/%s", baseURI, requestPath)
|
||||
ctx.Request = httptest.NewRequest(requestMethod, requestURI, nil) // the endpoint we're hitting
|
||||
|
|
|
@ -25,7 +25,6 @@ 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/concurrency"
|
||||
|
@ -104,8 +103,8 @@ func (suite *FollowRequestStandardTestSuite) newContext(recorder *httptest.Respo
|
|||
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
|
||||
ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"])
|
||||
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
baseURI := fmt.Sprintf("%s://%s", protocol, host)
|
||||
requestURI := fmt.Sprintf("%s/%s", baseURI, requestPath)
|
||||
|
|
|
@ -26,7 +26,6 @@ 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/instance"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/concurrency"
|
||||
|
@ -108,8 +107,8 @@ func (suite *InstanceStandardTestSuite) newContext(recorder *httptest.ResponseRe
|
|||
ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["admin_account"])
|
||||
ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["admin_account"])
|
||||
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
baseURI := fmt.Sprintf("%s://%s", protocol, host)
|
||||
requestURI := fmt.Sprintf("%s/%s", baseURI, requestPath)
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
||||
|
@ -41,7 +40,7 @@ func (m *Module) InstanceInformationGETHandler(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
|
||||
instance, err := m.processor.InstanceGet(c.Request.Context(), host)
|
||||
if err != nil {
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
|
@ -133,11 +132,10 @@ func validateCreateMedia(form *model.AttachmentRequest) error {
|
|||
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)
|
||||
maxVideoSize := config.GetMediaVideoMaxSize()
|
||||
maxImageSize := config.GetMediaImageMaxSize()
|
||||
minDescriptionChars := config.GetMediaDescriptionMinChars()
|
||||
maxDescriptionChars := config.GetMediaDescriptionMaxChars()
|
||||
|
||||
// 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
|
||||
|
|
|
@ -33,7 +33,6 @@ import (
|
|||
"codeberg.org/gruf/go-store/kv"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/suite"
|
||||
mediamodule "github.com/superseriousbusiness/gotosocial/internal/api/client/media"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
|
@ -261,7 +260,7 @@ func (suite *MediaCreateTestSuite) TestMediaCreateLongDescription() {
|
|||
|
||||
func (suite *MediaCreateTestSuite) TestMediaCreateTooShortDescription() {
|
||||
// set the min description length
|
||||
viper.Set(config.Keys.MediaDescriptionMinChars, 500)
|
||||
config.SetMediaDescriptionMinChars(500)
|
||||
|
||||
// set up the context for the request
|
||||
t := suite.testTokens["local_account_1"]
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
|
@ -141,9 +140,8 @@ func (m *Module) MediaPUTHandler(c *gin.Context) {
|
|||
}
|
||||
|
||||
func validateUpdateMedia(form *model.AttachmentUpdateRequest) error {
|
||||
keys := config.Keys
|
||||
minDescriptionChars := viper.GetInt(keys.MediaDescriptionMinChars)
|
||||
maxDescriptionChars := viper.GetInt(keys.MediaDescriptionMaxChars)
|
||||
minDescriptionChars := config.GetMediaDescriptionMinChars()
|
||||
maxDescriptionChars := config.GetMediaDescriptionMaxChars()
|
||||
|
||||
if form.Description != nil {
|
||||
if len(*form.Description) < minDescriptionChars || len(*form.Description) > maxDescriptionChars {
|
||||
|
|
|
@ -31,7 +31,6 @@ import (
|
|||
"codeberg.org/gruf/go-store/kv"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/suite"
|
||||
mediamodule "github.com/superseriousbusiness/gotosocial/internal/api/client/media"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
|
@ -188,7 +187,7 @@ func (suite *MediaUpdateTestSuite) TestUpdateImage() {
|
|||
|
||||
func (suite *MediaUpdateTestSuite) TestUpdateImageShortDescription() {
|
||||
// set the min description length
|
||||
viper.Set(config.Keys.MediaDescriptionMinChars, 50)
|
||||
config.SetMediaDescriptionMinChars(50)
|
||||
|
||||
toUpdate := suite.testAttachments["local_account_1_unattached_1"]
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
|
@ -130,12 +129,11 @@ func validateCreateStatus(form *model.AdvancedStatusCreateForm) error {
|
|||
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)
|
||||
maxChars := config.GetStatusesMaxChars()
|
||||
maxMediaFiles := config.GetStatusesMediaMaxFiles()
|
||||
maxPollOptions := config.GetStatusesPollMaxOptions()
|
||||
maxPollChars := config.GetStatusesPollOptionMaxChars()
|
||||
maxCwChars := config.GetStatusesCWMaxChars()
|
||||
|
||||
// validate status
|
||||
if form.Status != "" {
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
@ -90,8 +89,8 @@ func (m *Module) WebfingerGETRequest(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
accountDomain := viper.GetString(config.Keys.AccountDomain)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
accountDomain := config.GetAccountDomain()
|
||||
host := config.GetHost()
|
||||
|
||||
if requestedAccountDomain != accountDomain && requestedAccountDomain != host {
|
||||
l.Debugf("aborting request because accountDomain %s does not belong to this instance", requestedAccountDomain)
|
||||
|
|
|
@ -27,7 +27,6 @@ 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"
|
||||
|
@ -46,7 +45,7 @@ func (suite *WebfingerGetTestSuite) TestFingerUser() {
|
|||
targetAccount := suite.testAccounts["local_account_1"]
|
||||
|
||||
// setup request
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, host)
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
|
@ -69,8 +68,9 @@ func (suite *WebfingerGetTestSuite) TestFingerUser() {
|
|||
}
|
||||
|
||||
func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByHost() {
|
||||
viper.Set(config.Keys.Host, "gts.example.org")
|
||||
viper.Set(config.Keys.AccountDomain, "example.org")
|
||||
config.SetHost("gts.example.org")
|
||||
config.SetAccountDomain("example.org")
|
||||
|
||||
clientWorker := concurrency.NewWorkerPool[messages.FromClientAPI](-1, -1)
|
||||
fedWorker := concurrency.NewWorkerPool[messages.FromFederator](-1, -1)
|
||||
suite.processor = processing.NewProcessor(suite.tc, suite.federator, testrig.NewTestOauthServer(suite.db), testrig.NewTestMediaManager(suite.db, suite.storage), suite.storage, suite.db, suite.emailSender, clientWorker, fedWorker)
|
||||
|
@ -82,7 +82,7 @@ func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByHo
|
|||
}
|
||||
|
||||
// setup request
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, host)
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
|
@ -105,8 +105,9 @@ func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByHo
|
|||
}
|
||||
|
||||
func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByAccountDomain() {
|
||||
viper.Set(config.Keys.Host, "gts.example.org")
|
||||
viper.Set(config.Keys.AccountDomain, "example.org")
|
||||
config.SetHost("gts.example.org")
|
||||
config.SetAccountDomain("example.org")
|
||||
|
||||
clientWorker := concurrency.NewWorkerPool[messages.FromClientAPI](-1, -1)
|
||||
fedWorker := concurrency.NewWorkerPool[messages.FromFederator](-1, -1)
|
||||
suite.processor = processing.NewProcessor(suite.tc, suite.federator, testrig.NewTestOauthServer(suite.db), testrig.NewTestMediaManager(suite.db, suite.storage), suite.storage, suite.db, suite.emailSender, clientWorker, fedWorker)
|
||||
|
@ -118,7 +119,7 @@ func (suite *WebfingerGetTestSuite) TestFingerUserWithDifferentAccountDomainByAc
|
|||
}
|
||||
|
||||
// setup request
|
||||
accountDomain := viper.GetString(config.Keys.AccountDomain)
|
||||
accountDomain := config.GetAccountDomain()
|
||||
requestPath := fmt.Sprintf("/%s?resource=acct:%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, accountDomain)
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
|
@ -144,7 +145,7 @@ func (suite *WebfingerGetTestSuite) TestFingerUserWithoutAcct() {
|
|||
targetAccount := suite.testAccounts["local_account_1"]
|
||||
|
||||
// setup request -- leave out the 'acct:' prefix, which is prettymuch what pixelfed currently does
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
requestPath := fmt.Sprintf("/%s?resource=%s@%s", webfinger.WebfingerBasePath, targetAccount.Username, host)
|
||||
|
||||
recorder := httptest.NewRecorder()
|
||||
|
|
139
internal/config/config.go
Normal file
139
internal/config/config.go
Normal file
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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 (
|
||||
"reflect"
|
||||
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
// cfgtype is the reflected type information of Configuration{}.
|
||||
var cfgtype = reflect.TypeOf(Configuration{})
|
||||
|
||||
// fieldtag will fetch the string value for the given tag name
|
||||
// on the given field name in the Configuration{} struct.
|
||||
func fieldtag(field, tag string) string {
|
||||
sfield, ok := cfgtype.FieldByName(field)
|
||||
if !ok {
|
||||
panic("unknown struct field")
|
||||
}
|
||||
return sfield.Tag.Get(tag)
|
||||
}
|
||||
|
||||
// Configuration represents global GTS server runtime configuration.
|
||||
//
|
||||
// Please note that if you update this struct's fields or tags, you
|
||||
// will need to regenerate the global Getter/Setter helpers by running:
|
||||
// `go run ./internal/config/gen/ -out ./internal/config/helpers.gen.go`
|
||||
type Configuration struct {
|
||||
LogLevel string `name:"log-level" usage:"Log level to run at: [trace, debug, info, warn, fatal]"`
|
||||
LogDbQueries bool `name:"log-db-queries" usage:"Log database queries verbosely when log-level is trace or debug"`
|
||||
ApplicationName string `name:"application-name" usage:"Name of the application, used in various places internally"`
|
||||
ConfigPath string `name:"config-path" usage:"Path to a file containing gotosocial configuration. Values set in this file will be overwritten by values set as env vars or arguments"`
|
||||
Host string `name:"host" usage:"Hostname to use for the server (eg., example.org, gotosocial.whatever.com). DO NOT change this on a server that's already run!"`
|
||||
AccountDomain string `name:"account-domain" usage:"Domain to use in account names (eg., example.org, whatever.com). If not set, will default to the setting for host. DO NOT change this on a server that's already run!"`
|
||||
Protocol string `name:"protocol" usage:"Protocol to use for the REST api of the server (only use http if you are debugging or behind a reverse proxy!)"`
|
||||
BindAddress string `name:"bind-address" usage:"Bind address to use for the GoToSocial server (eg., 0.0.0.0, 172.138.0.9, [::], localhost). For ipv6, enclose the address in square brackets, eg [2001:db8::fed1]. Default binds to all interfaces."`
|
||||
Port int `name:"port" usage:"Port to use for GoToSocial. Change this to 443 if you're running the binary directly on the host machine."`
|
||||
TrustedProxies []string `name:"trusted-proxies" usage:"Proxies to trust when parsing x-forwarded headers into real IPs."`
|
||||
SoftwareVersion string `name:"software-version" usage:""`
|
||||
|
||||
DbType string `name:"db-type" usage:"Database type: eg., postgres"`
|
||||
DbAddress string `name:"db-address" usage:"Database ipv4 address, hostname, or filename"`
|
||||
DbPort int `name:"db-port" usage:"Database port"`
|
||||
DbUser string `name:"db-user" usage:"Database username"`
|
||||
DbPassword string `name:"db-password" usage:"Database password"`
|
||||
DbDatabase string `name:"db-database" usage:"Database name"`
|
||||
DbTLSMode string `name:"db-tls-mode" usage:"Database tls mode"`
|
||||
DbTLSCACert string `name:"db-tls-ca-cert" usage:"Path to CA cert for db tls connection"`
|
||||
|
||||
WebTemplateBaseDir string `name:"web-template-base-dir" usage:"Basedir for html templating files for rendering pages and composing emails."`
|
||||
WebAssetBaseDir string `name:"web-asset-base-dir" usage:"Directory to serve static assets from, accessible at example.org/assets/"`
|
||||
|
||||
AccountsRegistrationOpen bool `name:"accounts-registration-open" usage:"Allow anyone to submit an account signup request. If false, server will be invite-only."`
|
||||
AccountsApprovalRequired bool `name:"accounts-approval-required" usage:"Do account signups require approval by an admin or moderator before user can log in? If false, new registrations will be automatically approved."`
|
||||
AccountsReasonRequired bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"`
|
||||
|
||||
MediaImageMaxSize int `name:"media-image-max-size" usage:"Max size of accepted images in bytes"`
|
||||
MediaVideoMaxSize int `name:"media-video-max-size" usage:"Max size of accepted videos in bytes"`
|
||||
MediaDescriptionMinChars int `name:"media-description-min-chars" usage:"Min required chars for an image description"`
|
||||
MediaDescriptionMaxChars int `name:"media-description-max-chars" usage:"Max permitted chars for an image description"`
|
||||
MediaRemoteCacheDays int `name:"media-remote-cache-days" usage:"Number of days to locally cache media from remote instances. If set to 0, remote media will be kept indefinitely."`
|
||||
|
||||
StorageBackend string `name:"storage-backend" usage:"Storage backend to use for media attachments"`
|
||||
StorageLocalBasePath string `name:"storage-local-base-path" usage:"Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir."`
|
||||
|
||||
StatusesMaxChars int `name:"statuses-max-chars" usage:"Max permitted characters for posted statuses"`
|
||||
StatusesCWMaxChars int `name:"statuses-cw-max-chars" usage:"Max permitted characters for content/spoiler warnings on statuses"`
|
||||
StatusesPollMaxOptions int `name:"statuses-poll-max-options" usage:"Max amount of options permitted on a poll"`
|
||||
StatusesPollOptionMaxChars int `name:"statuses-poll-option-max-chars" usage:"Max amount of characters for a poll option"`
|
||||
StatusesMediaMaxFiles int `name:"statuses-media-max-files" usage:"Maximum number of media files/attachments per status"`
|
||||
|
||||
LetsEncryptEnabled bool `name:"letsencrypt-enabled" usage:"Enable letsencrypt TLS certs for this server. If set to true, then cert dir also needs to be set (or take the default)."`
|
||||
LetsEncryptPort int `name:"letsencrypt-port" usage:"Port to listen on for letsencrypt certificate challenges. Must not be the same as the GtS webserver/API port."`
|
||||
LetsEncryptCertDir string `name:"letsencrypt-cert-dir" usage:"Directory to store acquired letsencrypt certificates."`
|
||||
LetsEncryptEmailAddress string `name:"letsencrypt-email-address" usage:"Email address to use when requesting letsencrypt certs. Will receive updates on cert expiry etc."`
|
||||
|
||||
OIDCEnabled bool `name:"oidc-enabled" usage:"Enabled OIDC authorization for this instance. If set to true, then the other OIDC flags must also be set."`
|
||||
OIDCIdpName string `name:"oidc-idp-name" usage:"Name of the OIDC identity provider. Will be shown to the user when logging in."`
|
||||
OIDCSkipVerification bool `name:"oidc-skip-verification" usage:"Skip verification of tokens returned by the OIDC provider. Should only be set to 'true' for testing purposes, never in a production environment!"`
|
||||
OIDCIssuer string `name:"oidc-issuer" usage:"Address of the OIDC issuer. Should be the web address, including protocol, at which the issuer can be reached. Eg., 'https://example.org/auth'"`
|
||||
OIDCClientID string `name:"oidc-client-id" usage:"ClientID of GoToSocial, as registered with the OIDC provider."`
|
||||
OIDCClientSecret string `name:"oidc-client-secret" usage:"ClientSecret of GoToSocial, as registered with the OIDC provider."`
|
||||
OIDCScopes []string `name:"oidc-scopes" usage:"OIDC scopes."`
|
||||
|
||||
SMTPHost string `name:"smtp-host" usage:"Host of the smtp server. Eg., 'smtp.eu.mailgun.org'"`
|
||||
SMTPPort int `name:"smtp-port" usage:"Port of the smtp server. Eg., 587"`
|
||||
SMTPUsername string `name:"smtp-username" usage:"Username to authenticate with the smtp server as. Eg., 'postmaster@mail.example.org'"`
|
||||
SMTPPassword string `name:"smtp-password" usage:"Password to pass to the smtp server."`
|
||||
SMTPFrom string `name:"smtp-from" usage:"Address to use as the 'from' field of the email. Eg., 'gotosocial@example.org'"`
|
||||
|
||||
SyslogEnabled bool `name:"syslog-enabled" usage:"Enable the syslog logging hook. Logs will be mirrored to the configured destination."`
|
||||
SyslogProtocol string `name:"syslog-protocol" usage:"Protocol to use when directing logs to syslog. Leave empty to connect to local syslog."`
|
||||
SyslogAddress string `name:"syslog-address" usage:"Address:port to send syslog logs to. Leave empty to connect to local syslog."`
|
||||
|
||||
// TODO: move these elsewhere, these are more ephemeral vs long-running flags like above
|
||||
AdminAccountUsername string `name:"username" usage:"the username to create/delete/etc"`
|
||||
AdminAccountEmail string `name:"email" usage:"the email address of this account"`
|
||||
AdminAccountPassword string `name:"password" usage:"the password to set for this account"`
|
||||
AdminTransPath string `name:"path" usage:"the path of the file to import from/export to"`
|
||||
}
|
||||
|
||||
// MarshalMap will marshal current Configuration into a map structure (useful for JSON).
|
||||
func (cfg *Configuration) MarshalMap() (map[string]interface{}, error) {
|
||||
var dst map[string]interface{}
|
||||
dec, _ := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||
TagName: "name",
|
||||
Result: &dst,
|
||||
})
|
||||
if err := dec.Decode(cfg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
// UnmarshalMap will unmarshal a map structure into the receiving Configuration.
|
||||
func (cfg *Configuration) UnmarshalMap(src map[string]interface{}) error {
|
||||
dec, _ := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
|
||||
TagName: "name",
|
||||
Result: cfg,
|
||||
})
|
||||
return dec.Decode(src)
|
||||
}
|
|
@ -20,9 +20,9 @@ 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{
|
||||
// Defaults contains a populated Configuration with reasonable defaults. Note that
|
||||
// if you use this, you will still need to set Host, and, if desired, ConfigPath.
|
||||
var Defaults = Configuration{
|
||||
LogLevel: "info",
|
||||
LogDbQueries: false,
|
||||
ApplicationName: "gotosocial",
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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/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
|
||||
}
|
157
internal/config/flags.go
Normal file
157
internal/config/flags.go
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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/spf13/cobra"
|
||||
)
|
||||
|
||||
// TODO: consolidate these methods into the Configuration{} or ConfigState{} structs.
|
||||
|
||||
// AddGlobalFlags will attach global configuration flags to given cobra command, loading defaults from global config.
|
||||
func AddGlobalFlags(cmd *cobra.Command) {
|
||||
Config(func(cfg *Configuration) {
|
||||
// General
|
||||
cmd.PersistentFlags().String(ApplicationNameFlag(), cfg.ApplicationName, fieldtag("ApplicationName", "usage"))
|
||||
cmd.PersistentFlags().String(HostFlag(), cfg.Host, fieldtag("Host", "usage"))
|
||||
cmd.PersistentFlags().String(AccountDomainFlag(), cfg.AccountDomain, fieldtag("AccountDomain", "usage"))
|
||||
cmd.PersistentFlags().String(ProtocolFlag(), cfg.Protocol, fieldtag("Protocol", "usage"))
|
||||
cmd.PersistentFlags().String(LogLevelFlag(), cfg.LogLevel, fieldtag("LogLevel", "usage"))
|
||||
cmd.PersistentFlags().Bool(LogDbQueriesFlag(), cfg.LogDbQueries, fieldtag("LogDbQueries", "usage"))
|
||||
cmd.PersistentFlags().String(ConfigPathFlag(), cfg.ConfigPath, fieldtag("ConfigPath", "usage"))
|
||||
|
||||
// Database
|
||||
cmd.PersistentFlags().String(DbTypeFlag(), cfg.DbType, fieldtag("DbType", "usage"))
|
||||
cmd.PersistentFlags().String(DbAddressFlag(), cfg.DbAddress, fieldtag("DbAddress", "usage"))
|
||||
cmd.PersistentFlags().Int(DbPortFlag(), cfg.DbPort, fieldtag("DbPort", "usage"))
|
||||
cmd.PersistentFlags().String(DbUserFlag(), cfg.DbUser, fieldtag("DbUser", "usage"))
|
||||
cmd.PersistentFlags().String(DbPasswordFlag(), cfg.DbPassword, fieldtag("DbPassword", "usage"))
|
||||
cmd.PersistentFlags().String(DbDatabaseFlag(), cfg.DbDatabase, fieldtag("DbDatabase", "usage"))
|
||||
cmd.PersistentFlags().String(DbTLSModeFlag(), cfg.DbTLSMode, fieldtag("DbTLSMode", "usage"))
|
||||
cmd.PersistentFlags().String(DbTLSCACertFlag(), cfg.DbTLSCACert, fieldtag("DbTLSCACert", "usage"))
|
||||
})
|
||||
}
|
||||
|
||||
// AddServerFlags will attach server configuration flags to given cobra command, loading defaults from global config.
|
||||
func AddServerFlags(cmd *cobra.Command) {
|
||||
Config(func(cfg *Configuration) {
|
||||
// Router
|
||||
cmd.PersistentFlags().String(BindAddressFlag(), cfg.BindAddress, fieldtag("BindAddress", "usage"))
|
||||
cmd.PersistentFlags().Int(PortFlag(), cfg.Port, fieldtag("Port", "usage"))
|
||||
cmd.PersistentFlags().StringSlice(TrustedProxiesFlag(), cfg.TrustedProxies, fieldtag("TrustedProxies", "usage"))
|
||||
|
||||
// Template
|
||||
cmd.Flags().String(WebTemplateBaseDirFlag(), cfg.WebTemplateBaseDir, fieldtag("WebTemplateBaseDir", "usage"))
|
||||
cmd.Flags().String(WebAssetBaseDirFlag(), cfg.WebAssetBaseDir, fieldtag("WebAssetBaseDir", "usage"))
|
||||
|
||||
// Accounts
|
||||
cmd.Flags().Bool(AccountsRegistrationOpenFlag(), cfg.AccountsRegistrationOpen, fieldtag("AccountsRegistrationOpen", "usage"))
|
||||
cmd.Flags().Bool(AccountsApprovalRequiredFlag(), cfg.AccountsApprovalRequired, fieldtag("AccountsApprovalRequired", "usage"))
|
||||
cmd.Flags().Bool(AccountsReasonRequiredFlag(), cfg.AccountsReasonRequired, fieldtag("AccountsReasonRequired", "usage"))
|
||||
|
||||
// Media
|
||||
cmd.Flags().Int(MediaImageMaxSizeFlag(), cfg.MediaImageMaxSize, fieldtag("MediaImageMaxSize", "usage"))
|
||||
cmd.Flags().Int(MediaVideoMaxSizeFlag(), cfg.MediaVideoMaxSize, fieldtag("MediaVideoMaxSize", "usage"))
|
||||
cmd.Flags().Int(MediaDescriptionMinCharsFlag(), cfg.MediaDescriptionMinChars, fieldtag("MediaDescriptionMinChars", "usage"))
|
||||
cmd.Flags().Int(MediaDescriptionMaxCharsFlag(), cfg.MediaDescriptionMaxChars, fieldtag("MediaDescriptionMaxChars", "usage"))
|
||||
cmd.Flags().Int(MediaRemoteCacheDaysFlag(), cfg.MediaRemoteCacheDays, fieldtag("MediaRemoteCacheDays", "usage"))
|
||||
|
||||
// Storage
|
||||
cmd.Flags().String(StorageBackendFlag(), cfg.StorageBackend, fieldtag("StorageBackend", "usage"))
|
||||
cmd.Flags().String(StorageLocalBasePathFlag(), cfg.StorageLocalBasePath, fieldtag("StorageLocalBasePath", "usage"))
|
||||
|
||||
// Statuses
|
||||
cmd.Flags().Int(StatusesMaxCharsFlag(), cfg.StatusesMaxChars, fieldtag("StatusesMaxChars", "usage"))
|
||||
cmd.Flags().Int(StatusesCWMaxCharsFlag(), cfg.StatusesCWMaxChars, fieldtag("StatusesCWMaxChars", "usage"))
|
||||
cmd.Flags().Int(StatusesPollMaxOptionsFlag(), cfg.StatusesPollMaxOptions, fieldtag("StatusesPollMaxOptions", "usage"))
|
||||
cmd.Flags().Int(StatusesPollOptionMaxCharsFlag(), cfg.StatusesPollOptionMaxChars, fieldtag("StatusesPollOptionMaxChars", "usage"))
|
||||
cmd.Flags().Int(StatusesMediaMaxFilesFlag(), cfg.StatusesMediaMaxFiles, fieldtag("StatusesMediaMaxFiles", "usage"))
|
||||
|
||||
// LetsEncrypt
|
||||
cmd.Flags().Bool(LetsEncryptEnabledFlag(), cfg.LetsEncryptEnabled, fieldtag("LetsEncryptEnabled", "usage"))
|
||||
cmd.Flags().Int(LetsEncryptPortFlag(), cfg.LetsEncryptPort, fieldtag("LetsEncryptPort", "usage"))
|
||||
cmd.Flags().String(LetsEncryptCertDirFlag(), cfg.LetsEncryptCertDir, fieldtag("LetsEncryptCertDir", "usage"))
|
||||
cmd.Flags().String(LetsEncryptEmailAddressFlag(), cfg.LetsEncryptEmailAddress, fieldtag("LetsEncryptEmailAddress", "usage"))
|
||||
|
||||
// OIDC
|
||||
cmd.Flags().Bool(OIDCEnabledFlag(), cfg.OIDCEnabled, fieldtag("OIDCEnabled", "usage"))
|
||||
cmd.Flags().String(OIDCIdpNameFlag(), cfg.OIDCIdpName, fieldtag("OIDCIdpName", "usage"))
|
||||
cmd.Flags().Bool(OIDCSkipVerificationFlag(), cfg.OIDCSkipVerification, fieldtag("OIDCSkipVerification", "usage"))
|
||||
cmd.Flags().String(OIDCIssuerFlag(), cfg.OIDCIssuer, fieldtag("OIDCIssuer", "usage"))
|
||||
cmd.Flags().String(OIDCClientIDFlag(), cfg.OIDCClientID, fieldtag("OIDCClientID", "usage"))
|
||||
cmd.Flags().String(OIDCClientSecretFlag(), cfg.OIDCClientSecret, fieldtag("OIDCClientSecret", "usage"))
|
||||
cmd.Flags().StringSlice(OIDCScopesFlag(), cfg.OIDCScopes, fieldtag("OIDCScopes", "usage"))
|
||||
|
||||
// SMTP
|
||||
cmd.Flags().String(SMTPHostFlag(), cfg.SMTPHost, fieldtag("SMTPHost", "usage"))
|
||||
cmd.Flags().Int(SMTPPortFlag(), cfg.SMTPPort, fieldtag("SMTPPort", "usage"))
|
||||
cmd.Flags().String(SMTPUsernameFlag(), cfg.SMTPUsername, fieldtag("SMTPUsername", "usage"))
|
||||
cmd.Flags().String(SMTPPasswordFlag(), cfg.SMTPPassword, fieldtag("SMTPPassword", "usage"))
|
||||
cmd.Flags().String(SMTPFromFlag(), cfg.SMTPFrom, fieldtag("SMTPFrom", "usage"))
|
||||
|
||||
// Syslog
|
||||
cmd.Flags().Bool(SyslogEnabledFlag(), cfg.SyslogEnabled, fieldtag("SyslogEnabled", "usage"))
|
||||
cmd.Flags().String(SyslogProtocolFlag(), cfg.SyslogProtocol, fieldtag("SyslogProtocol", "usage"))
|
||||
cmd.Flags().String(SyslogAddressFlag(), cfg.SyslogAddress, fieldtag("SyslogAddress", "usage"))
|
||||
})
|
||||
}
|
||||
|
||||
// AddAdminAccount attaches flags pertaining to admin account actions.
|
||||
func AddAdminAccount(cmd *cobra.Command) {
|
||||
name := AdminAccountUsernameFlag()
|
||||
usage := fieldtag("AdminAccountUsername", "usage")
|
||||
cmd.Flags().String(name, "", usage) // REQUIRED
|
||||
if err := cmd.MarkFlagRequired(name); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// AddAdminAccountPassword attaches flags pertaining to admin account password reset.
|
||||
func AddAdminAccountPassword(cmd *cobra.Command) {
|
||||
name := AdminAccountPasswordFlag()
|
||||
usage := fieldtag("AdminAccountPassword", "usage")
|
||||
cmd.Flags().String(name, "", usage) // REQUIRED
|
||||
if err := cmd.MarkFlagRequired(name); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// AddAdminAccountCreate attaches flags pertaining to admin account creation.
|
||||
func AddAdminAccountCreate(cmd *cobra.Command) {
|
||||
// Requires both account and password
|
||||
AddAdminAccount(cmd)
|
||||
AddAdminAccountPassword(cmd)
|
||||
|
||||
name := AdminAccountEmailFlag()
|
||||
usage := fieldtag("AdminAccountEmail", "usage")
|
||||
cmd.Flags().String(name, "", usage) // REQUIRED
|
||||
if err := cmd.MarkFlagRequired(name); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// AddAdminTrans attaches flags pertaining to import/export commands.
|
||||
func AddAdminTrans(cmd *cobra.Command) {
|
||||
name := AdminTransPathFlag()
|
||||
usage := fieldtag("AdminTransPath", "usage")
|
||||
cmd.Flags().String(name, "", usage) // REQUIRED
|
||||
if err := cmd.MarkFlagRequired(name); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
112
internal/config/gen/gen.go
Normal file
112
internal/config/gen/gen.go
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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 main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
const license = `/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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/>.
|
||||
*/
|
||||
`
|
||||
|
||||
func main() {
|
||||
var (
|
||||
out string
|
||||
gen string
|
||||
)
|
||||
|
||||
// Load runtime config flags
|
||||
flag.StringVar(&out, "out", "", "Generated file output path")
|
||||
flag.StringVar(&gen, "gen", "helpers", "Type of file to generate (helpers)")
|
||||
flag.Parse()
|
||||
|
||||
// Open output file path
|
||||
output, err := os.OpenFile(out, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0o644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
switch gen {
|
||||
// Generate config field helper methods
|
||||
case "helpers":
|
||||
fmt.Fprint(output, "// THIS IS A GENERATED FILE, DO NOT EDIT BY HAND\n")
|
||||
fmt.Fprint(output, license)
|
||||
fmt.Fprint(output, "package config\n\n")
|
||||
t := reflect.TypeOf(config.Configuration{})
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
field := t.Field(i)
|
||||
|
||||
// ConfigState structure helper methods
|
||||
fmt.Fprintf(output, "// Get%s safely fetches the Configuration value for state's '%s' field\n", field.Name, field.Name)
|
||||
fmt.Fprintf(output, "func (st *ConfigState) Get%s() (v %s) {\n", field.Name, field.Type.String())
|
||||
fmt.Fprintf(output, "\tst.mutex.Lock()\n")
|
||||
fmt.Fprintf(output, "\tv = st.config.%s\n", field.Name)
|
||||
fmt.Fprintf(output, "\tst.mutex.Unlock()\n")
|
||||
fmt.Fprintf(output, "\treturn\n")
|
||||
fmt.Fprintf(output, "}\n\n")
|
||||
fmt.Fprintf(output, "// Set%s safely sets the Configuration value for state's '%s' field\n", field.Name, field.Name)
|
||||
fmt.Fprintf(output, "func (st *ConfigState) Set%s(v %s) {\n", field.Name, field.Type.String())
|
||||
fmt.Fprintf(output, "\tst.mutex.Lock()\n")
|
||||
fmt.Fprintf(output, "\tdefer st.mutex.Unlock()\n")
|
||||
fmt.Fprintf(output, "\tst.config.%s = v\n", field.Name)
|
||||
fmt.Fprintf(output, "\tst.reloadToViper()\n")
|
||||
fmt.Fprintf(output, "}\n\n")
|
||||
|
||||
// Global ConfigState helper methods
|
||||
// TODO: remove when we pass around a ConfigState{}
|
||||
fmt.Fprintf(output, "// %sFlag returns the flag name for the '%s' field\n", field.Name, field.Name)
|
||||
fmt.Fprintf(output, "func %sFlag() string { return \"%s\" }\n\n", field.Name, field.Tag.Get("name"))
|
||||
fmt.Fprintf(output, "// Get%s safely fetches the value for global configuration '%s' field\n", field.Name, field.Name)
|
||||
fmt.Fprintf(output, "func Get%[1]s() %[2]s { return global.Get%[1]s() }\n\n", field.Name, field.Type.String())
|
||||
fmt.Fprintf(output, "// Set%s safely sets the value for global configuration '%s' field\n", field.Name, field.Name)
|
||||
fmt.Fprintf(output, "func Set%[1]s(v %[2]s) { global.Set%[1]s(v) }\n\n", field.Name, field.Type.String())
|
||||
}
|
||||
_ = output.Close()
|
||||
_ = exec.Command("gofmt", "-w", out).Run()
|
||||
|
||||
// The plain here is that eventually we might be able
|
||||
// to generate an example configuration from struct tags
|
||||
|
||||
// Unknown type
|
||||
default:
|
||||
panic("unknown generation type: " + gen)
|
||||
}
|
||||
}
|
53
internal/config/global.go
Normal file
53
internal/config/global.go
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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/spf13/cobra"
|
||||
|
||||
var global *ConfigState
|
||||
|
||||
func init() {
|
||||
// init global state
|
||||
global = NewState()
|
||||
}
|
||||
|
||||
// TODO: in the future we should move away from using globals in this config
|
||||
// package, and instead pass the ConfigState round in a global gts state.
|
||||
|
||||
// Config provides you safe access to the global configuration.
|
||||
func Config(fn func(cfg *Configuration)) {
|
||||
global.Config(fn)
|
||||
}
|
||||
|
||||
// Reload will reload the current configuration values from file.
|
||||
func Reload() error {
|
||||
return global.Reload()
|
||||
}
|
||||
|
||||
// LoadEarlyFlags will bind specific flags from given Cobra command to global viper
|
||||
// instance, and load the current configuration values. This is useful for flags like
|
||||
// .ConfigPath which have to parsed first in order to perform early configuration load.
|
||||
func LoadEarlyFlags(cmd *cobra.Command) error {
|
||||
return global.LoadEarlyFlags(cmd)
|
||||
}
|
||||
|
||||
// BindFlags binds given command's pflags to the global viper instance.
|
||||
func BindFlags(cmd *cobra.Command) error {
|
||||
return global.BindFlags(cmd)
|
||||
}
|
1494
internal/config/helpers.gen.go
Normal file
1494
internal/config/helpers.gen.go
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,182 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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
|
||||
LogDbQueries 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
|
||||
MediaRemoteCacheDays string
|
||||
|
||||
// storage
|
||||
StorageBackend string
|
||||
StorageLocalBasePath 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
|
||||
|
||||
// syslog
|
||||
SyslogEnabled string
|
||||
SyslogProtocol string
|
||||
SyslogAddress 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",
|
||||
LogDbQueries: "log-db-queries",
|
||||
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",
|
||||
MediaRemoteCacheDays: "media-remote-cache-days",
|
||||
|
||||
StorageBackend: "storage-backend",
|
||||
StorageLocalBasePath: "storage-local-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",
|
||||
|
||||
SyslogEnabled: "syslog-enabled",
|
||||
SyslogProtocol: "syslog-protocol",
|
||||
SyslogAddress: "syslog-address",
|
||||
|
||||
AdminAccountUsername: "username",
|
||||
AdminAccountEmail: "email",
|
||||
AdminAccountPassword: "password",
|
||||
AdminTransPath: "path",
|
||||
}
|
136
internal/config/state.go
Normal file
136
internal/config/state.go
Normal file
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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 (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// ConfigState manages safe concurrent access to Configuration{} values,
|
||||
// and provides ease of linking them (including reloading) via viper to
|
||||
// environment, CLI and configuration file variables.
|
||||
type ConfigState struct { //nolint
|
||||
viper *viper.Viper
|
||||
config Configuration
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
// NewState returns a new initialized ConfigState instance.
|
||||
func NewState() *ConfigState {
|
||||
viper := viper.New()
|
||||
|
||||
// Flag 'some-flag-name' becomes env var 'GTS_SOME_FLAG_NAME'
|
||||
viper.SetEnvPrefix("gts")
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
||||
|
||||
// Load appropriate named vals from env
|
||||
viper.AutomaticEnv()
|
||||
|
||||
// Create new ConfigState with defaults
|
||||
state := &ConfigState{
|
||||
viper: viper,
|
||||
config: Defaults,
|
||||
}
|
||||
|
||||
// Perform initial load into viper
|
||||
state.reloadToViper()
|
||||
|
||||
return state
|
||||
}
|
||||
|
||||
// Config provides safe access to the ConfigState's contained Configuration,
|
||||
// and will reload the current Configuration back into viper settings.
|
||||
func (st *ConfigState) Config(fn func(*Configuration)) {
|
||||
st.mutex.Lock()
|
||||
defer func() {
|
||||
st.reloadToViper()
|
||||
st.mutex.Unlock()
|
||||
}()
|
||||
fn(&st.config)
|
||||
}
|
||||
|
||||
// Viper provides safe access to the ConfigState's contained viper instance,
|
||||
// and will reload the current viper setting state back into Configuration.
|
||||
func (st *ConfigState) Viper(fn func(*viper.Viper)) {
|
||||
st.mutex.Lock()
|
||||
defer func() {
|
||||
st.reloadFromViper()
|
||||
st.mutex.Unlock()
|
||||
}()
|
||||
fn(st.viper)
|
||||
}
|
||||
|
||||
// LoadEarlyFlags will bind specific flags from given Cobra command to ConfigState's viper
|
||||
// instance, and load the current configuration values. This is useful for flags like
|
||||
// .ConfigPath which have to parsed first in order to perform early configuration load.
|
||||
func (st *ConfigState) LoadEarlyFlags(cmd *cobra.Command) (err error) {
|
||||
name := ConfigPathFlag()
|
||||
flag := cmd.Flags().Lookup(name)
|
||||
st.Viper(func(v *viper.Viper) {
|
||||
err = v.BindPFlag(name, flag)
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// BindFlags will bind given Cobra command's pflags to this ConfigState's viper instance.
|
||||
func (st *ConfigState) BindFlags(cmd *cobra.Command) (err error) {
|
||||
st.Viper(func(v *viper.Viper) {
|
||||
err = v.BindPFlags(cmd.Flags())
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Reload will reload the Configuration values from ConfigState's viper instance, and from file if set.
|
||||
func (st *ConfigState) Reload() (err error) {
|
||||
st.Viper(func(v *viper.Viper) {
|
||||
if st.config.ConfigPath != "" {
|
||||
// Ensure configuration path is set
|
||||
v.SetConfigFile(st.config.ConfigPath)
|
||||
|
||||
// Read in configuration from file
|
||||
if err = v.ReadInConfig(); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// reloadToViper will reload Configuration{} values into viper.
|
||||
func (st *ConfigState) reloadToViper() {
|
||||
raw, err := st.config.MarshalMap()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if err := st.viper.MergeConfigMap(raw); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// reloadFromViper will reload Configuration{} values from viper.
|
||||
func (st *ConfigState) reloadFromViper() {
|
||||
err := st.config.UnmarshalMap(st.viper.AllSettings())
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
|
@ -24,7 +24,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// Validate validates global config settings which don't have defaults, to make sure they are set sensibly.
|
||||
|
@ -32,22 +31,21 @@ func Validate() error {
|
|||
errs := []error{}
|
||||
|
||||
// host
|
||||
if viper.GetString(Keys.Host) == "" {
|
||||
errs = append(errs, fmt.Errorf("%s must be set", Keys.Host))
|
||||
if GetHost() == "" {
|
||||
errs = append(errs, fmt.Errorf("%s must be set", HostFlag()))
|
||||
}
|
||||
|
||||
// protocol
|
||||
protocol := viper.GetString(Keys.Protocol)
|
||||
switch protocol {
|
||||
switch proto := GetProtocol(); proto {
|
||||
case "https":
|
||||
// no problem
|
||||
break
|
||||
case "http":
|
||||
logrus.Warnf("%s was set to 'http'; this should *only* be used for debugging and tests!", Keys.Protocol)
|
||||
logrus.Warnf("%s was set to 'http'; this should *only* be used for debugging and tests!", ProtocolFlag())
|
||||
case "":
|
||||
errs = append(errs, fmt.Errorf("%s must be set", Keys.Protocol))
|
||||
errs = append(errs, fmt.Errorf("%s must be set", ProtocolFlag()))
|
||||
default:
|
||||
errs = append(errs, fmt.Errorf("%s must be set to either http or https, provided value was %s", Keys.Protocol, protocol))
|
||||
errs = append(errs, fmt.Errorf("%s must be set to either http or https, provided value was %s", ProtocolFlag(), proto))
|
||||
}
|
||||
|
||||
if len(errs) > 0 {
|
||||
|
|
|
@ -21,7 +21,6 @@ package config_test
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/testrig"
|
||||
|
@ -41,7 +40,7 @@ func (suite *ConfigValidateTestSuite) TestValidateConfigOK() {
|
|||
func (suite *ConfigValidateTestSuite) TestValidateConfigNoHost() {
|
||||
testrig.InitTestConfig()
|
||||
|
||||
viper.Set(config.Keys.Host, "")
|
||||
config.SetHost("")
|
||||
|
||||
err := config.Validate()
|
||||
suite.EqualError(err, "host must be set")
|
||||
|
@ -50,7 +49,7 @@ func (suite *ConfigValidateTestSuite) TestValidateConfigNoHost() {
|
|||
func (suite *ConfigValidateTestSuite) TestValidateConfigNoProtocol() {
|
||||
testrig.InitTestConfig()
|
||||
|
||||
viper.Set(config.Keys.Protocol, "")
|
||||
config.SetProtocol("")
|
||||
|
||||
err := config.Validate()
|
||||
suite.EqualError(err, "protocol must be set")
|
||||
|
@ -59,8 +58,8 @@ func (suite *ConfigValidateTestSuite) TestValidateConfigNoProtocol() {
|
|||
func (suite *ConfigValidateTestSuite) TestValidateConfigNoProtocolOrHost() {
|
||||
testrig.InitTestConfig()
|
||||
|
||||
viper.Set(config.Keys.Host, "")
|
||||
viper.Set(config.Keys.Protocol, "")
|
||||
config.SetHost("")
|
||||
config.SetProtocol("")
|
||||
|
||||
err := config.Validate()
|
||||
suite.EqualError(err, "host must be set; protocol must be set")
|
||||
|
@ -69,7 +68,7 @@ func (suite *ConfigValidateTestSuite) TestValidateConfigNoProtocolOrHost() {
|
|||
func (suite *ConfigValidateTestSuite) TestValidateConfigBadProtocol() {
|
||||
testrig.InitTestConfig()
|
||||
|
||||
viper.Set(config.Keys.Protocol, "foo")
|
||||
config.SetProtocol("foo")
|
||||
|
||||
err := config.Validate()
|
||||
suite.EqualError(err, "protocol must be set to either http or https, provided value was foo")
|
||||
|
@ -78,8 +77,8 @@ func (suite *ConfigValidateTestSuite) TestValidateConfigBadProtocol() {
|
|||
func (suite *ConfigValidateTestSuite) TestValidateConfigBadProtocolNoHost() {
|
||||
testrig.InitTestConfig()
|
||||
|
||||
viper.Set(config.Keys.Host, "")
|
||||
viper.Set(config.Keys.Protocol, "foo")
|
||||
config.SetHost("")
|
||||
config.SetProtocol("foo")
|
||||
|
||||
err := config.Validate()
|
||||
suite.EqualError(err, "host must be set; protocol must be set to either http or https, provided value was foo")
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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
|
||||
LogDbQueries bool
|
||||
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
|
||||
MediaRemoteCacheDays int
|
||||
|
||||
StorageBackend string
|
||||
StorageLocalBasePath 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
|
||||
|
||||
SyslogEnabled bool
|
||||
SyslogProtocol string
|
||||
SyslogAddress string
|
||||
|
||||
AdminAccountUsername string
|
||||
AdminAccountEmail string
|
||||
AdminAccountPassword string
|
||||
AdminTransPath string
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
/*
|
||||
GoToSocial
|
||||
Copyright (C) 2021-2022 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 (
|
||||
"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
|
||||
}
|
|
@ -25,7 +25,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/cache"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
|
@ -133,9 +132,8 @@ 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 = ?", host).
|
||||
Where("account.username = ?", config.GetHost()).
|
||||
WhereGroup(" AND ", whereEmptyOrNull("domain"))
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
@ -178,7 +177,7 @@ func (a *adminDB) NewSignup(ctx context.Context, username string, reason string,
|
|||
}
|
||||
|
||||
func (a *adminDB) CreateInstanceAccount(ctx context.Context) db.Error {
|
||||
username := viper.GetString(config.Keys.Host)
|
||||
username := config.GetHost()
|
||||
|
||||
q := a.conn.
|
||||
NewSelect().
|
||||
|
@ -237,8 +236,8 @@ func (a *adminDB) CreateInstanceAccount(ctx context.Context) db.Error {
|
|||
}
|
||||
|
||||
func (a *adminDB) CreateInstanceInstance(ctx context.Context) db.Error {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
// check if instance entry already exists
|
||||
q := a.conn.
|
||||
|
|
|
@ -35,7 +35,6 @@ 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"
|
||||
|
@ -120,7 +119,7 @@ func doMigration(ctx context.Context, db *bun.DB) error {
|
|||
func NewBunDBService(ctx context.Context) (db.DB, error) {
|
||||
var conn *DBConn
|
||||
var err error
|
||||
dbType := strings.ToLower(viper.GetString(config.Keys.DbType))
|
||||
dbType := strings.ToLower(config.GetDbType())
|
||||
|
||||
switch dbType {
|
||||
case dbTypePostgres:
|
||||
|
@ -139,7 +138,7 @@ func NewBunDBService(ctx context.Context) (db.DB, error) {
|
|||
|
||||
// add a hook to log queries and the time they take
|
||||
// only do this for logging where performance isn't 1st concern
|
||||
if logrus.GetLevel() >= logrus.DebugLevel && viper.GetBool(config.Keys.LogDbQueries) {
|
||||
if logrus.GetLevel() >= logrus.DebugLevel && config.GetLogDbQueries() {
|
||||
conn.DB.AddQueryHook(newDebugQueryHook())
|
||||
}
|
||||
|
||||
|
@ -209,9 +208,9 @@ func NewBunDBService(ctx context.Context) (db.DB, error) {
|
|||
|
||||
func sqliteConn(ctx context.Context) (*DBConn, error) {
|
||||
// validate db address has actually been set
|
||||
dbAddress := viper.GetString(config.Keys.DbAddress)
|
||||
dbAddress := config.GetDbAddress()
|
||||
if dbAddress == "" {
|
||||
return nil, fmt.Errorf("'%s' was not set when attempting to start sqlite", config.Keys.DbAddress)
|
||||
return nil, fmt.Errorf("'%s' was not set when attempting to start sqlite", config.DbAddressFlag())
|
||||
}
|
||||
|
||||
// Drop anything fancy from DB address
|
||||
|
@ -282,27 +281,21 @@ func pgConn(ctx context.Context) (*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() (*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))
|
||||
if strings.ToUpper(config.GetDbType()) != db.DBTypePostgres {
|
||||
return nil, fmt.Errorf("expected db type of %s but got %s", db.DBTypePostgres, config.DbTypeFlag())
|
||||
}
|
||||
|
||||
// these are all optional, the db adapter figures out defaults
|
||||
port := viper.GetInt(keys.DbPort)
|
||||
address := viper.GetString(keys.DbAddress)
|
||||
username := viper.GetString(keys.DbUser)
|
||||
password := viper.GetString(keys.DbPassword)
|
||||
address := config.GetDbAddress()
|
||||
|
||||
// validate database
|
||||
database := viper.GetString(keys.DbDatabase)
|
||||
database := config.GetDbDatabase()
|
||||
if database == "" {
|
||||
return nil, errors.New("no database set")
|
||||
}
|
||||
|
||||
var tlsConfig *tls.Config
|
||||
tlsMode := viper.GetString(keys.DbTLSMode)
|
||||
switch tlsMode {
|
||||
switch config.GetDbTLSMode() {
|
||||
case dbTLSModeDisable, dbTLSModeUnset:
|
||||
break // nothing to do
|
||||
case dbTLSModeEnable:
|
||||
|
@ -313,13 +306,12 @@ func deriveBunDBPGOptions() (*pgx.ConnConfig, error) {
|
|||
case dbTLSModeRequire:
|
||||
tlsConfig = &tls.Config{
|
||||
InsecureSkipVerify: false,
|
||||
ServerName: viper.GetString(keys.DbAddress),
|
||||
ServerName: address,
|
||||
MinVersion: tls.VersionTLS12,
|
||||
}
|
||||
}
|
||||
|
||||
caCertPath := viper.GetString(keys.DbTLSCACert)
|
||||
if tlsConfig != nil && caCertPath != "" {
|
||||
if certPath := config.GetDbTLSCACert(); tlsConfig != nil && certPath != "" {
|
||||
// load the system cert pool first -- we'll append the given CA cert to this
|
||||
certPool, err := x509.SystemCertPool()
|
||||
if err != nil {
|
||||
|
@ -327,24 +319,24 @@ func deriveBunDBPGOptions() (*pgx.ConnConfig, error) {
|
|||
}
|
||||
|
||||
// open the file itself and make sure there's something in it
|
||||
caCertBytes, err := os.ReadFile(caCertPath)
|
||||
caCertBytes, err := os.ReadFile(certPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error opening CA certificate at %s: %s", caCertPath, err)
|
||||
return nil, fmt.Errorf("error opening CA certificate at %s: %s", certPath, err)
|
||||
}
|
||||
if len(caCertBytes) == 0 {
|
||||
return nil, fmt.Errorf("ca cert at %s was empty", caCertPath)
|
||||
return nil, fmt.Errorf("ca cert at %s was empty", certPath)
|
||||
}
|
||||
|
||||
// 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", caCertPath)
|
||||
return nil, fmt.Errorf("could not parse cert at %s into PEM", certPath)
|
||||
}
|
||||
|
||||
// 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", caCertPath, err)
|
||||
return nil, fmt.Errorf("could not parse cert at %s into x509 certificate: %s", certPath, err)
|
||||
}
|
||||
|
||||
// we're happy, add it to the existing pool and then use this pool in our tls config
|
||||
|
@ -356,21 +348,21 @@ func deriveBunDBPGOptions() (*pgx.ConnConfig, error) {
|
|||
if address != "" {
|
||||
cfg.Host = address
|
||||
}
|
||||
if port > 0 {
|
||||
if port := config.GetPort(); port > 0 {
|
||||
cfg.Port = uint16(port)
|
||||
}
|
||||
if username != "" {
|
||||
cfg.User = username
|
||||
if u := config.GetDbUser(); u != "" {
|
||||
cfg.User = u
|
||||
}
|
||||
if password != "" {
|
||||
cfg.Password = password
|
||||
if p := config.GetDbPassword(); p != "" {
|
||||
cfg.Password = p
|
||||
}
|
||||
if tlsConfig != nil {
|
||||
cfg.TLSConfig = tlsConfig
|
||||
}
|
||||
cfg.Database = database
|
||||
cfg.PreferSimpleProtocol = true
|
||||
cfg.RuntimeParams["application_name"] = viper.GetString(keys.ApplicationName)
|
||||
cfg.RuntimeParams["application_name"] = config.GetApplicationName()
|
||||
|
||||
return cfg, nil
|
||||
}
|
||||
|
@ -387,8 +379,8 @@ func tweakConnectionValues(sqldb *sql.DB) {
|
|||
*/
|
||||
|
||||
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)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
newTags := []*gtsmodel.Tag{}
|
||||
for _, t := range tags {
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db/bundb"
|
||||
|
@ -41,7 +40,7 @@ func (suite *BundbNewTestSuite) TestCreateNewDB() {
|
|||
|
||||
func (suite *BundbNewTestSuite) TestCreateNewSqliteDBNoAddress() {
|
||||
// create a new db with no address specified
|
||||
viper.Set(config.Keys.DbAddress, "")
|
||||
config.SetDbAddress("")
|
||||
db, err := bundb.NewBunDBService(context.Background())
|
||||
suite.EqualError(err, "'db-address' was not set when attempting to start sqlite")
|
||||
suite.Nil(db)
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||
|
@ -35,7 +34,7 @@ type domainDB struct {
|
|||
}
|
||||
|
||||
func (d *domainDB) IsDomainBlocked(ctx context.Context, domain string) (bool, db.Error) {
|
||||
if domain == "" || domain == viper.GetString(config.Keys.Host) {
|
||||
if domain == "" || domain == config.GetHost() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"context"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
|
@ -41,8 +40,7 @@ func (i *instanceDB) CountInstanceUsers(ctx context.Context, domain string) (int
|
|||
Where("username != ?", domain).
|
||||
Where("? IS NULL", bun.Ident("suspended_at"))
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if domain == host {
|
||||
if domain == config.GetHost() {
|
||||
// if the domain is *this* domain, just count where the domain field is null
|
||||
q = q.WhereGroup(" AND ", whereEmptyOrNull("domain"))
|
||||
} else {
|
||||
|
@ -61,8 +59,7 @@ func (i *instanceDB) CountInstanceStatuses(ctx context.Context, domain string) (
|
|||
NewSelect().
|
||||
Model(&[]*gtsmodel.Status{})
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if domain == host {
|
||||
if domain == config.GetHost() {
|
||||
// if the domain is *this* domain, just count where local is true
|
||||
q = q.Where("local = ?", true)
|
||||
} else {
|
||||
|
@ -83,8 +80,7 @@ func (i *instanceDB) CountInstanceDomains(ctx context.Context, domain string) (i
|
|||
NewSelect().
|
||||
Model(&[]*gtsmodel.Instance{})
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if domain == host {
|
||||
if domain == config.GetHost() {
|
||||
// if the domain is *this* domain, just count other instances it knows about
|
||||
// exclude domains that are blocked
|
||||
q = q.
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"net/smtp"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
|
@ -43,7 +42,7 @@ func (s *sender) SendConfirmEmail(toAddress string, data ConfirmData) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logrus.WithField("func", "SendConfirmEmail").Trace(s.hostAddress + "\n" + viper.GetString(config.Keys.SMTPUsername) + ":password" + "\n" + s.from + "\n" + toAddress + "\n\n" + string(msg) + "\n")
|
||||
logrus.WithField("func", "SendConfirmEmail").Trace(s.hostAddress + "\n" + config.GetSMTPUsername() + ":password" + "\n" + s.from + "\n" + toAddress + "\n\n" + string(msg) + "\n")
|
||||
return smtp.SendMail(s.hostAddress, s.auth, s.from, []string{toAddress}, msg)
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"text/template"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
|
@ -32,7 +31,7 @@ import (
|
|||
//
|
||||
// Passing a nil function is also acceptable, in which case the send functions will just return nil.
|
||||
func NewNoopSender(sendCallback func(toAddress string, message string)) (Sender, error) {
|
||||
templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir)
|
||||
templateBaseDir := config.GetWebTemplateBaseDir()
|
||||
|
||||
t, err := loadTemplates(templateBaseDir)
|
||||
if err != nil {
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"net/smtp"
|
||||
"text/template"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
|
@ -38,19 +37,17 @@ type Sender interface {
|
|||
|
||||
// NewSender returns a new email Sender interface with the given configuration, or an error if something goes wrong.
|
||||
func NewSender() (Sender, error) {
|
||||
keys := config.Keys
|
||||
|
||||
templateBaseDir := viper.GetString(keys.WebTemplateBaseDir)
|
||||
templateBaseDir := config.GetWebTemplateBaseDir()
|
||||
t, err := loadTemplates(templateBaseDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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)
|
||||
username := config.GetSMTPUsername()
|
||||
password := config.GetSMTPPassword()
|
||||
host := config.GetSMTPHost()
|
||||
port := config.GetSMTPPort()
|
||||
from := config.GetSMTPFrom()
|
||||
|
||||
return &sender{
|
||||
hostAddress: fmt.Sprintf("%s:%d", host, port),
|
||||
|
|
|
@ -29,7 +29,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/go-fed/httpsig"
|
||||
"github.com/superseriousbusiness/activity/pub"
|
||||
|
@ -168,8 +167,7 @@ func (f *federator) AuthenticateFederatedRequest(ctx context.Context, requestedU
|
|||
requestingRemoteAccount := >smodel.Account{}
|
||||
requestingLocalAccount := >smodel.Account{}
|
||||
requestingHost := requestingPublicKeyID.Host
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if strings.EqualFold(requestingHost, host) {
|
||||
if host := config.GetHost(); 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)
|
||||
|
|
|
@ -24,7 +24,6 @@ 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/uris"
|
||||
|
@ -45,8 +44,7 @@ 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
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if statusIRI.Host == host {
|
||||
if statusIRI.Host == config.GetHost() {
|
||||
l.Debug("iri belongs to us, bailing")
|
||||
return nil
|
||||
}
|
||||
|
@ -80,8 +78,7 @@ 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
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if statusIRI.Host == host {
|
||||
if statusIRI.Host == config.GetHost() {
|
||||
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
|
||||
|
@ -132,8 +129,7 @@ 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
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if statusIRI.Host == host {
|
||||
if statusIRI.Host == config.GetHost() {
|
||||
l.Debug("iri belongs to us, bailing")
|
||||
return nil
|
||||
}
|
||||
|
@ -209,8 +205,7 @@ pageLoop:
|
|||
continue
|
||||
}
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if itemURI.Host == host {
|
||||
if itemURI.Host == config.GetHost() {
|
||||
// skip if the reply is from us -- we already have it then
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/activity/streams"
|
||||
"github.com/superseriousbusiness/activity/streams/vocab"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
@ -80,7 +79,7 @@ func (f *federatingDB) SetInbox(c context.Context, inbox vocab.ActivityStreamsOr
|
|||
// The library makes this call only after acquiring a lock first.
|
||||
func (f *federatingDB) InboxesForIRI(c context.Context, iri *url.URL) (inboxIRIs []*url.URL, err error) {
|
||||
// check if this is a followers collection iri for a local account...
|
||||
if iri.Host == viper.GetString(config.Keys.Host) && uris.IsFollowersPath(iri) {
|
||||
if iri.Host == config.GetHost() && uris.IsFollowersPath(iri) {
|
||||
localAccountUsername, err := uris.ParseFollowersPath(iri)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("couldn't extract local account username from uri %s: %s", iri, err)
|
||||
|
|
|
@ -24,7 +24,6 @@ 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"
|
||||
|
@ -44,8 +43,7 @@ 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
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if id.Host != host {
|
||||
if host := config.GetHost(); id.Host != host {
|
||||
l.Tracef("we DO NOT own activity because the host is %s not %s", id.Host, host)
|
||||
return false, nil
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ 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"
|
||||
|
@ -125,8 +124,7 @@ func (f *federatingDB) Update(ctx context.Context, asType vocab.Type) error {
|
|||
return fmt.Errorf("UPDATE: error converting to account: %s", err)
|
||||
}
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if updatedAcct.Domain == host {
|
||||
if updatedAcct.Domain == config.GetHost() {
|
||||
// no need to update local accounts
|
||||
// in fact, if we do this will break the shit out of things so do NOT
|
||||
return nil
|
||||
|
|
|
@ -26,7 +26,6 @@ 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"
|
||||
|
@ -209,9 +208,7 @@ func (f *federatingDB) NewID(ctx context.Context, t vocab.Type) (idURL *url.URL,
|
|||
return nil, err
|
||||
}
|
||||
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
return url.Parse(fmt.Sprintf("%s://%s/%s", protocol, host, newID))
|
||||
return url.Parse(fmt.Sprintf("%s://%s/%s", config.GetProtocol(), config.GetHost(), newID))
|
||||
}
|
||||
|
||||
// ActorForOutbox fetches the actor's IRI for the given outbox IRI.
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
|
||||
"github.com/sirupsen/logrus"
|
||||
lSyslog "github.com/sirupsen/logrus/hooks/syslog"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
|
@ -48,12 +47,9 @@ func Initialize() error {
|
|||
FullTimestamp: true,
|
||||
})
|
||||
|
||||
keys := config.Keys
|
||||
|
||||
// check if a desired log level has been set
|
||||
logLevel := viper.GetString(keys.LogLevel)
|
||||
if logLevel != "" {
|
||||
level, err := logrus.ParseLevel(logLevel)
|
||||
if lvl := config.GetLogLevel(); lvl != "" {
|
||||
level, err := logrus.ParseLevel(lvl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -65,9 +61,9 @@ func Initialize() error {
|
|||
}
|
||||
|
||||
// check if syslog has been enabled, and configure it if so
|
||||
if syslogEnabled := viper.GetBool(keys.SyslogEnabled); syslogEnabled {
|
||||
protocol := viper.GetString(keys.SyslogProtocol)
|
||||
address := viper.GetString(keys.SyslogAddress)
|
||||
if config.GetSyslogEnabled() {
|
||||
protocol := config.GetSyslogProtocol()
|
||||
address := config.GetSyslogAddress()
|
||||
|
||||
hook, err := lSyslog.NewSyslogHook(protocol, address, syslog.LOG_INFO, "")
|
||||
if err != nil {
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
|
||||
"github.com/google/uuid"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/testrig"
|
||||
|
@ -45,9 +44,10 @@ type SyslogTestSuite struct {
|
|||
func (suite *SyslogTestSuite) SetupTest() {
|
||||
testrig.InitTestConfig()
|
||||
|
||||
viper.Set(config.Keys.SyslogEnabled, true)
|
||||
viper.Set(config.Keys.SyslogProtocol, "udp")
|
||||
viper.Set(config.Keys.SyslogAddress, "127.0.0.1:42069")
|
||||
config.SetSyslogEnabled(true)
|
||||
config.SetSyslogProtocol("udp")
|
||||
config.SetSyslogAddress("127.0.0.1:42069")
|
||||
|
||||
server, channel, err := testrig.InitTestSyslog()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -93,9 +93,10 @@ func (suite *SyslogTestSuite) TestSyslogLongMessageUnixgram() {
|
|||
syslogServer := server
|
||||
syslogChannel := channel
|
||||
|
||||
viper.Set(config.Keys.SyslogEnabled, true)
|
||||
viper.Set(config.Keys.SyslogProtocol, "unixgram")
|
||||
viper.Set(config.Keys.SyslogAddress, socketPath)
|
||||
config.SetSyslogEnabled(true)
|
||||
config.SetSyslogProtocol("unixgram")
|
||||
config.SetSyslogAddress(socketPath)
|
||||
|
||||
testrig.InitTestLog()
|
||||
|
||||
logrus.Warn(longMessage)
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"codeberg.org/gruf/go-store/kv"
|
||||
"github.com/robfig/cron/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/concurrency"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
|
@ -212,7 +211,7 @@ func scheduleCleanupJobs(m *manager) error {
|
|||
}
|
||||
|
||||
// start remote cache cleanup cronjob if configured
|
||||
if mediaRemoteCacheDays := viper.GetInt(config.Keys.MediaRemoteCacheDays); mediaRemoteCacheDays > 0 {
|
||||
if mediaRemoteCacheDays := config.GetMediaRemoteCacheDays(); mediaRemoteCacheDays > 0 {
|
||||
if _, err := c.AddFunc("@midnight", func() {
|
||||
begin := time.Now()
|
||||
pruned, err := m.PruneAllRemote(pruneCtx, mediaRemoteCacheDays)
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
@ -56,36 +55,33 @@ type idp struct {
|
|||
// 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) (IDP, error) {
|
||||
keys := config.Keys
|
||||
|
||||
oidcEnabled := viper.GetBool(keys.OIDCEnabled)
|
||||
if !oidcEnabled {
|
||||
if !config.GetOIDCEnabled() {
|
||||
// oidc isn't enabled so we don't need to do anything
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// validate config fields
|
||||
idpName := viper.GetString(keys.OIDCIdpName)
|
||||
idpName := config.GetOIDCIdpName()
|
||||
if idpName == "" {
|
||||
return nil, fmt.Errorf("not set: IDPName")
|
||||
}
|
||||
|
||||
issuer := viper.GetString(keys.OIDCIssuer)
|
||||
issuer := config.GetOIDCIssuer()
|
||||
if issuer == "" {
|
||||
return nil, fmt.Errorf("not set: Issuer")
|
||||
}
|
||||
|
||||
clientID := viper.GetString(keys.OIDCClientID)
|
||||
clientID := config.GetOIDCClientID()
|
||||
if clientID == "" {
|
||||
return nil, fmt.Errorf("not set: ClientID")
|
||||
}
|
||||
|
||||
clientSecret := viper.GetString(keys.OIDCClientSecret)
|
||||
clientSecret := config.GetOIDCClientSecret()
|
||||
if clientSecret == "" {
|
||||
return nil, fmt.Errorf("not set: ClientSecret")
|
||||
}
|
||||
|
||||
scopes := viper.GetStringSlice(keys.OIDCScopes)
|
||||
scopes := config.GetOIDCScopes()
|
||||
if len(scopes) == 0 {
|
||||
return nil, fmt.Errorf("not set: Scopes")
|
||||
}
|
||||
|
@ -95,8 +91,8 @@ func NewIDP(ctx context.Context) (IDP, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
protocol := viper.GetString(keys.Protocol)
|
||||
host := viper.GetString(keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
oauth2Config := oauth2.Config{
|
||||
// client_id and client_secret of the client.
|
||||
|
@ -120,8 +116,7 @@ func NewIDP(ctx context.Context) (IDP, error) {
|
|||
ClientID: clientID,
|
||||
}
|
||||
|
||||
skipVerification := viper.GetBool(keys.OIDCSkipVerification)
|
||||
if skipVerification {
|
||||
if config.GetOIDCSkipVerification() {
|
||||
oidcConf.SkipClientIDCheck = true
|
||||
oidcConf.SkipExpiryCheck = true
|
||||
oidcConf.SkipIssuerCheck = true
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
|
@ -53,9 +52,8 @@ 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)
|
||||
reasonRequired := config.GetAccountsReasonRequired()
|
||||
approvalRequired := config.GetAccountsApprovalRequired()
|
||||
|
||||
// don't store a reason if we don't require one
|
||||
reason := form.Reason
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"mime/multipart"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
|
@ -142,7 +141,7 @@ func (p *processor) Update(ctx context.Context, account *gtsmodel.Account, form
|
|||
// parsing and checking the image, and doing the necessary updates in the database for this to become
|
||||
// the account's new avatar image.
|
||||
func (p *processor) UpdateAvatar(ctx context.Context, avatar *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) {
|
||||
maxImageSize := viper.GetInt(config.Keys.MediaImageMaxSize)
|
||||
maxImageSize := config.GetMediaImageMaxSize()
|
||||
if int(avatar.Size) > maxImageSize {
|
||||
return nil, fmt.Errorf("UpdateAvatar: avatar with size %d exceeded max image size of %d bytes", avatar.Size, maxImageSize)
|
||||
}
|
||||
|
@ -169,7 +168,7 @@ func (p *processor) UpdateAvatar(ctx context.Context, avatar *multipart.FileHead
|
|||
// parsing and checking the image, and doing the necessary updates in the database for this to become
|
||||
// the account's new header image.
|
||||
func (p *processor) UpdateHeader(ctx context.Context, header *multipart.FileHeader, accountID string) (*gtsmodel.MediaAttachment, error) {
|
||||
maxImageSize := viper.GetInt(config.Keys.MediaImageMaxSize)
|
||||
maxImageSize := config.GetMediaImageMaxSize()
|
||||
if int(header.Size) > maxImageSize {
|
||||
return nil, fmt.Errorf("UpdateHeader: header with size %d exceeded max image size of %d bytes", header.Size, maxImageSize)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ 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"
|
||||
|
@ -64,8 +63,8 @@ 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)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
nextLink := &url.URL{
|
||||
Scheme: protocol,
|
||||
|
|
|
@ -23,7 +23,6 @@ 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"
|
||||
|
@ -40,8 +39,8 @@ 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)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
return &apimodel.WellKnownResponse{
|
||||
Links: []apimodel.Link{
|
||||
|
@ -54,8 +53,8 @@ func (p *processor) GetNodeInfoRel(ctx context.Context, request *http.Request) (
|
|||
}
|
||||
|
||||
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)
|
||||
openRegistration := config.GetAccountsRegistrationOpen()
|
||||
softwareVersion := config.GetSoftwareVersion()
|
||||
|
||||
return &apimodel.Nodeinfo{
|
||||
Version: nodeInfoVersion,
|
||||
|
|
|
@ -22,7 +22,6 @@ 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"
|
||||
|
@ -43,9 +42,9 @@ 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)
|
||||
accountDomain := config.GetAccountDomain()
|
||||
if accountDomain == "" {
|
||||
accountDomain = viper.GetString(config.Keys.Host)
|
||||
accountDomain = config.GetHost()
|
||||
}
|
||||
|
||||
// return the webfinger representation
|
||||
|
|
|
@ -22,7 +22,6 @@ 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"
|
||||
|
@ -49,7 +48,7 @@ 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 := >smodel.Instance{}
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
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))
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ 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"
|
||||
|
@ -166,8 +165,7 @@ 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 := >smodel.Account{}
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
if domain == host {
|
||||
if domain == config.GetHost() {
|
||||
maybeAcct, err = p.db.GetLocalAccountByUsername(ctx, username)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("searchAccountByMention: error getting local account by username: %s", err)
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"net/url"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
@ -111,8 +110,8 @@ func StatusSkipInsertFunction() timeline.SkipInsertFunction {
|
|||
nextItemAccountID string,
|
||||
nextItemBoostOfID string,
|
||||
nextItemBoostOfAccountID string,
|
||||
depth int) (bool, error) {
|
||||
|
||||
depth int,
|
||||
) (bool, error) {
|
||||
// make sure we don't insert a duplicate
|
||||
if newItemID == nextItemID {
|
||||
return true, nil
|
||||
|
@ -148,8 +147,8 @@ 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)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
nextLink := &url.URL{
|
||||
Scheme: protocol,
|
||||
|
|
|
@ -25,7 +25,6 @@ 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"
|
||||
|
@ -34,9 +33,7 @@ import (
|
|||
"github.com/superseriousbusiness/gotosocial/internal/uris"
|
||||
)
|
||||
|
||||
var (
|
||||
oneWeek = 168 * time.Hour
|
||||
)
|
||||
var oneWeek = 168 * time.Hour
|
||||
|
||||
func (p *processor) SendConfirmEmail(ctx context.Context, user *gtsmodel.User, username string) error {
|
||||
if user.UnconfirmedEmail == "" || user.UnconfirmedEmail == user.Email {
|
||||
|
@ -57,7 +54,7 @@ func (p *processor) SendConfirmEmail(ctx context.Context, user *gtsmodel.User, u
|
|||
|
||||
// pull our instance entry from the database so we can greet the user nicely in the email
|
||||
instance := >smodel.Instance{}
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
if err := p.db.GetWhere(ctx, []db.Where{{Key: "domain", Value: host}}, instance); err != nil {
|
||||
return fmt.Errorf("SendConfirmEmail: error getting instance: %s", err)
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import (
|
|||
"codeberg.org/gruf/go-debug"
|
||||
"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"
|
||||
|
@ -70,16 +69,12 @@ 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() {
|
||||
var (
|
||||
keys = config.Keys
|
||||
|
||||
// listen is the server start function, by
|
||||
// default pointing to regular HTTP listener,
|
||||
// but updated to TLS if LetsEncrypt is enabled.
|
||||
listen = r.srv.ListenAndServe
|
||||
)
|
||||
listen := r.srv.ListenAndServe
|
||||
|
||||
if viper.GetBool(keys.LetsEncryptEnabled) {
|
||||
if config.GetLetsEncryptEnabled() {
|
||||
// LetsEncrypt support is enabled
|
||||
|
||||
// Prepare an HTTPS-redirect handler for LetsEncrypt fallback
|
||||
|
@ -97,8 +92,8 @@ func (r *router) Start() {
|
|||
srv := (*r.srv) //nolint
|
||||
srv.Handler = r.certManager.HTTPHandler(redirect)
|
||||
srv.Addr = fmt.Sprintf("%s:%d",
|
||||
viper.GetString(keys.BindAddress),
|
||||
viper.GetInt(keys.LetsEncryptPort),
|
||||
config.GetBindAddress(),
|
||||
config.GetLetsEncryptPort(),
|
||||
)
|
||||
|
||||
// Start the LetsEncrypt autocert manager HTTP server.
|
||||
|
@ -144,8 +139,6 @@ 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, 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
|
||||
|
@ -158,7 +151,7 @@ func New(ctx context.Context, db db.DB) (Router, error) {
|
|||
engine.MaxMultipartMemory = 8 << 20
|
||||
|
||||
// set up IP forwarding via x-forward-* headers.
|
||||
trustedProxies := viper.GetStringSlice(keys.TrustedProxies)
|
||||
trustedProxies := config.GetTrustedProxies()
|
||||
if err := engine.SetTrustedProxies(trustedProxies); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -187,8 +180,8 @@ func New(ctx context.Context, db db.DB) (Router, error) {
|
|||
}
|
||||
|
||||
// create the http server here, passing the gin engine as handler
|
||||
bindAddress := viper.GetString(keys.BindAddress)
|
||||
port := viper.GetInt(keys.Port)
|
||||
bindAddress := config.GetBindAddress()
|
||||
port := config.GetPort()
|
||||
listen := fmt.Sprintf("%s:%d", bindAddress, port)
|
||||
s := &http.Server{
|
||||
Addr: listen,
|
||||
|
@ -201,14 +194,14 @@ func New(ctx context.Context, 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)
|
||||
leEnabled := config.GetLetsEncryptEnabled()
|
||||
|
||||
var m *autocert.Manager
|
||||
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)
|
||||
host := config.GetHost()
|
||||
leCertDir := config.GetLetsEncryptCertDir()
|
||||
leEmailAddress := config.GetLetsEncryptEmailAddress()
|
||||
m = &autocert.Manager{
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(host),
|
||||
|
|
|
@ -28,7 +28,6 @@ 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"
|
||||
"golang.org/x/net/idna"
|
||||
|
@ -38,9 +37,9 @@ import (
|
|||
func SessionOptions() sessions.Options {
|
||||
return sessions.Options{
|
||||
Path: "/",
|
||||
Domain: viper.GetString(config.Keys.Host),
|
||||
Domain: config.GetHost(),
|
||||
MaxAge: 120, // 2 minutes
|
||||
Secure: viper.GetString(config.Keys.Protocol) == "https", // only use cookie over https
|
||||
Secure: config.GetProtocol() == "https", // only use cookie over https
|
||||
HttpOnly: true, // exclude javascript from inspecting cookie
|
||||
SameSite: http.SameSiteStrictMode, // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1
|
||||
}
|
||||
|
@ -49,8 +48,8 @@ func SessionOptions() sessions.Options {
|
|||
// SessionName is a utility function that derives an appropriate session name from the hostname.
|
||||
func SessionName() (string, error) {
|
||||
// parse the protocol + host
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
u, err := url.Parse(fmt.Sprintf("%s://%s", protocol, host))
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
|
@ -21,7 +21,6 @@ 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"
|
||||
|
@ -37,8 +36,8 @@ func (suite *SessionTestSuite) SetupTest() {
|
|||
}
|
||||
|
||||
func (suite *SessionTestSuite) TestDeriveSessionNameLocalhostWithPort() {
|
||||
viper.Set(config.Keys.Protocol, "http")
|
||||
viper.Set(config.Keys.Host, "localhost:8080")
|
||||
config.SetProtocol("http")
|
||||
config.SetHost("localhost:8080")
|
||||
|
||||
sessionName, err := router.SessionName()
|
||||
suite.NoError(err)
|
||||
|
@ -46,8 +45,8 @@ func (suite *SessionTestSuite) TestDeriveSessionNameLocalhostWithPort() {
|
|||
}
|
||||
|
||||
func (suite *SessionTestSuite) TestDeriveSessionNameLocalhost() {
|
||||
viper.Set(config.Keys.Protocol, "http")
|
||||
viper.Set(config.Keys.Host, "localhost")
|
||||
config.SetProtocol("http")
|
||||
config.SetHost("localhost")
|
||||
|
||||
sessionName, err := router.SessionName()
|
||||
suite.NoError(err)
|
||||
|
@ -55,8 +54,8 @@ func (suite *SessionTestSuite) TestDeriveSessionNameLocalhost() {
|
|||
}
|
||||
|
||||
func (suite *SessionTestSuite) TestDeriveSessionNoProtocol() {
|
||||
viper.Set(config.Keys.Protocol, "")
|
||||
viper.Set(config.Keys.Host, "localhost")
|
||||
config.SetProtocol("")
|
||||
config.SetHost("localhost")
|
||||
|
||||
sessionName, err := router.SessionName()
|
||||
suite.EqualError(err, "parse \"://localhost\": missing protocol scheme")
|
||||
|
@ -64,9 +63,9 @@ func (suite *SessionTestSuite) TestDeriveSessionNoProtocol() {
|
|||
}
|
||||
|
||||
func (suite *SessionTestSuite) TestDeriveSessionNoHost() {
|
||||
viper.Set(config.Keys.Protocol, "https")
|
||||
viper.Set(config.Keys.Host, "")
|
||||
viper.Set(config.Keys.Port, 0)
|
||||
config.SetProtocol("https")
|
||||
config.SetHost("")
|
||||
config.SetPort(0)
|
||||
|
||||
sessionName, err := router.SessionName()
|
||||
suite.EqualError(err, "could not derive hostname without port from https://")
|
||||
|
@ -74,8 +73,8 @@ func (suite *SessionTestSuite) TestDeriveSessionNoHost() {
|
|||
}
|
||||
|
||||
func (suite *SessionTestSuite) TestDeriveSessionOK() {
|
||||
viper.Set(config.Keys.Protocol, "https")
|
||||
viper.Set(config.Keys.Host, "example.org")
|
||||
config.SetProtocol("https")
|
||||
config.SetHost("example.org")
|
||||
|
||||
sessionName, err := router.SessionName()
|
||||
suite.NoError(err)
|
||||
|
@ -83,8 +82,8 @@ func (suite *SessionTestSuite) TestDeriveSessionOK() {
|
|||
}
|
||||
|
||||
func (suite *SessionTestSuite) TestDeriveSessionIDNOK() {
|
||||
viper.Set(config.Keys.Protocol, "https")
|
||||
viper.Set(config.Keys.Host, "fóid.org")
|
||||
config.SetProtocol("https")
|
||||
config.SetHost("fóid.org")
|
||||
|
||||
sessionName, err := router.SessionName()
|
||||
suite.NoError(err)
|
||||
|
|
|
@ -26,16 +26,15 @@ 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(engine *gin.Engine) error {
|
||||
templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir)
|
||||
templateBaseDir := config.GetWebTemplateBaseDir()
|
||||
if templateBaseDir == "" {
|
||||
return fmt.Errorf("%s cannot be empty and must be a relative or absolute path", config.Keys.WebTemplateBaseDir)
|
||||
return fmt.Errorf("%s cannot be empty and must be a relative or absolute path", config.WebTemplateBaseDirFlag())
|
||||
}
|
||||
|
||||
templateBaseDir, err := filepath.Abs(templateBaseDir)
|
||||
|
|
|
@ -25,13 +25,11 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"runtime/debug"
|
||||
"time"
|
||||
|
||||
"codeberg.org/gruf/go-byteutil"
|
||||
"codeberg.org/gruf/go-cache/v2"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/activity/pub"
|
||||
"github.com/superseriousbusiness/activity/streams"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
@ -59,11 +57,9 @@ type controller struct {
|
|||
|
||||
// NewController returns an implementation of the Controller interface for creating new transports
|
||||
func NewController(db db.DB, federatingDB federatingdb.DB, clock pub.Clock, client pub.HttpClient) Controller {
|
||||
applicationName := viper.GetString(config.Keys.ApplicationName)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
|
||||
// Determine build information
|
||||
build, _ := debug.ReadBuildInfo()
|
||||
applicationName := config.GetApplicationName()
|
||||
host := config.GetHost()
|
||||
version := config.GetSoftwareVersion()
|
||||
|
||||
c := &controller{
|
||||
db: db,
|
||||
|
@ -71,7 +67,7 @@ func NewController(db db.DB, federatingDB federatingdb.DB, clock pub.Clock, clie
|
|||
clock: clock,
|
||||
client: client,
|
||||
cache: cache.New[string, *transport](),
|
||||
userAgent: fmt.Sprintf("%s; %s (gofed/activity gotosocial-%s)", applicationName, host, build.Main.Version),
|
||||
userAgent: fmt.Sprintf("%s; %s (gofed/activity gotosocial-%s)", applicationName, host, version),
|
||||
}
|
||||
|
||||
// Transport cache has TTL=1hr freq=1m
|
||||
|
@ -128,7 +124,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 = viper.GetString(config.Keys.Host)
|
||||
u = config.GetHost()
|
||||
} else {
|
||||
u = username
|
||||
}
|
||||
|
|
|
@ -27,7 +27,6 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
|
@ -69,7 +68,7 @@ outer:
|
|||
|
||||
func (t *transport) Deliver(ctx context.Context, b []byte, to *url.URL) error {
|
||||
// if the 'to' host is our own, just skip this delivery since we by definition already have the message!
|
||||
if to.Host == viper.GetString(config.Keys.Host) || to.Host == viper.GetString(config.Keys.AccountDomain) {
|
||||
if to.Host == config.GetHost() || to.Host == config.GetAccountDomain() {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/uris"
|
||||
)
|
||||
|
@ -33,7 +32,7 @@ import (
|
|||
func (t *transport) Dereference(ctx context.Context, iri *url.URL) ([]byte, error) {
|
||||
// if the request is to us, we can shortcut for certain URIs rather than going through
|
||||
// the normal request flow, thereby saving time and energy
|
||||
if iri.Host == viper.GetString(config.Keys.Host) {
|
||||
if iri.Host == config.GetHost() {
|
||||
if uris.IsFollowersPath(iri) {
|
||||
// the request is for followers of one of our accounts, which we can shortcut
|
||||
return t.controller.dereferenceLocalFollowers(ctx, iri)
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"net/url"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/activity/pub"
|
||||
"github.com/superseriousbusiness/activity/streams"
|
||||
"github.com/superseriousbusiness/activity/streams/vocab"
|
||||
|
@ -629,9 +628,9 @@ 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 == "" {
|
||||
accountDomain := viper.GetString(config.Keys.AccountDomain)
|
||||
accountDomain := config.GetAccountDomain()
|
||||
if accountDomain == "" {
|
||||
accountDomain = viper.GetString(config.Keys.Host)
|
||||
accountDomain = config.GetHost()
|
||||
}
|
||||
domain = accountDomain
|
||||
} else {
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
@ -575,9 +574,7 @@ func (c *converter) InstanceToAPIInstance(ctx context.Context, i *gtsmodel.Insta
|
|||
}
|
||||
|
||||
// if the requested instance is *this* instance, we can add some extra information
|
||||
keys := config.Keys
|
||||
host := viper.GetString(keys.Host)
|
||||
if i.Domain == host {
|
||||
if host := config.GetHost(); i.Domain == host {
|
||||
userCount, err := c.db.CountInstanceUsers(ctx, host)
|
||||
if err == nil {
|
||||
mi.Stats["user_count"] = userCount
|
||||
|
@ -593,14 +590,14 @@ func (c *converter) InstanceToAPIInstance(ctx context.Context, i *gtsmodel.Insta
|
|||
mi.Stats["domain_count"] = domainCount
|
||||
}
|
||||
|
||||
mi.Registrations = viper.GetBool(keys.AccountsRegistrationOpen)
|
||||
mi.ApprovalRequired = viper.GetBool(keys.AccountsApprovalRequired)
|
||||
mi.Registrations = config.GetAccountsRegistrationOpen()
|
||||
mi.ApprovalRequired = config.GetAccountsApprovalRequired()
|
||||
mi.InvitesEnabled = false // TODO
|
||||
mi.MaxTootChars = uint(viper.GetInt(keys.StatusesMaxChars))
|
||||
mi.MaxTootChars = uint(config.GetStatusesMaxChars())
|
||||
mi.URLS = &model.InstanceURLs{
|
||||
StreamingAPI: fmt.Sprintf("wss://%s", host),
|
||||
}
|
||||
mi.Version = viper.GetString(keys.SoftwareVersion)
|
||||
mi.Version = config.GetSoftwareVersion()
|
||||
}
|
||||
|
||||
// get the instance account if it exists and just skip if it doesn't
|
||||
|
|
|
@ -22,7 +22,6 @@ import (
|
|||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/regexes"
|
||||
)
|
||||
|
@ -79,47 +78,47 @@ 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, thisFollowID string) string {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
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, thisFavedID string) string {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
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, thisUpdateID string) string {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
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, thisBlockID string) string {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
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(token string) string {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
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) *UserURIs {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
|
||||
// The below URLs are used for serving web requests
|
||||
hostURL := fmt.Sprintf("%s://%s", protocol, host)
|
||||
|
@ -157,17 +156,15 @@ func GenerateURIsForAccount(username string) *UserURIs {
|
|||
// GenerateURIForAttachment generates a URI for an attachment/emoji/header etc.
|
||||
// Will produced something like https://example.org/fileserver/01FPST95B8FC3HG3AGCDKPQNQ2/attachment/original/01FPST9QK4V5XWS3F9Z4F2G1X7.gif
|
||||
func GenerateURIForAttachment(accountID string, mediaType string, mediaSize string, mediaID string, extension string) string {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
return fmt.Sprintf("%s://%s/%s/%s/%s/%s/%s.%s", protocol, host, FileserverPath, accountID, mediaType, mediaSize, mediaID, extension)
|
||||
}
|
||||
|
||||
// GenerateURIForEmoji generates an activitypub uri for a new emoji.
|
||||
func GenerateURIForEmoji(emojiID string) string {
|
||||
protocol := viper.GetString(config.Keys.Protocol)
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
|
||||
protocol := config.GetProtocol()
|
||||
host := config.GetHost()
|
||||
return fmt.Sprintf("%s://%s/%s/%s", protocol, host, EmojiPath, emojiID)
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,6 @@ 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"
|
||||
|
@ -54,9 +53,9 @@ type Module struct {
|
|||
|
||||
// New returns a new api.ClientModule for web pages.
|
||||
func New(processor processing.Processor) (api.ClientModule, error) {
|
||||
assetsBaseDir := viper.GetString(config.Keys.WebAssetBaseDir)
|
||||
assetsBaseDir := config.GetWebAssetBaseDir()
|
||||
if assetsBaseDir == "" {
|
||||
return nil, fmt.Errorf("%s cannot be empty and must be a relative or absolute path", config.Keys.WebAssetBaseDir)
|
||||
return nil, fmt.Errorf("%s cannot be empty and must be a relative or absolute path", config.WebAssetBaseDirFlag())
|
||||
}
|
||||
|
||||
assetsPath, err := filepath.Abs(assetsBaseDir)
|
||||
|
@ -106,7 +105,7 @@ func (m *Module) baseHandler(c *gin.Context) {
|
|||
l := logrus.WithField("func", "BaseGETHandler")
|
||||
l.Trace("serving index html")
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
instance, err := m.processor.InstanceGet(c.Request.Context(), host)
|
||||
if err != nil {
|
||||
l.Debugf("error getting instance from processor: %s", err)
|
||||
|
@ -124,7 +123,7 @@ func (m *Module) NotFoundHandler(c *gin.Context) {
|
|||
l := logrus.WithField("func", "404")
|
||||
l.Trace("serving 404 html")
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
instance, err := m.processor.InstanceGet(c.Request.Context(), host)
|
||||
if err != nil {
|
||||
l.Debugf("error getting instance from processor: %s", err)
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
|
@ -45,7 +44,7 @@ func (m *Module) confirmEmailGETHandler(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
instance, err := m.processor.InstanceGet(ctx, host)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
|
|
|
@ -27,7 +27,6 @@ import (
|
|||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/ap"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
@ -52,7 +51,7 @@ func (m *Module) profileTemplateHandler(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
instance, errWithCode := m.processor.InstanceGet(ctx, viper.GetString(config.Keys.Host))
|
||||
instance, errWithCode := m.processor.InstanceGet(ctx, config.GetHost())
|
||||
if errWithCode != nil {
|
||||
l.Debugf("error getting instance from processor: %s", errWithCode.Error())
|
||||
c.JSON(errWithCode.Code(), gin.H{"error": errWithCode.Safe()})
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
|
@ -57,7 +56,7 @@ func (m *Module) threadTemplateHandler(c *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
host := viper.GetString(config.Keys.Host)
|
||||
host := config.GetHost()
|
||||
instance, err := m.processor.InstanceGet(ctx, host)
|
||||
if err != nil {
|
||||
l.Debugf("error getting instance from processor: %s", err)
|
||||
|
|
|
@ -5,7 +5,7 @@ set -e
|
|||
echo "STARTING CLI TESTS"
|
||||
|
||||
echo "TEST_1 Make sure defaults are set correctly."
|
||||
TEST_1_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_1_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_1="$(go run ./cmd/gotosocial/... debug config)"
|
||||
if [ "${TEST_1}" != "${TEST_1_EXPECTED}" ]; then
|
||||
echo "TEST_1 not equal TEST_1_EXPECTED"
|
||||
|
@ -15,7 +15,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_2 Override db-address from default using cli flag."
|
||||
TEST_2_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_2_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_2="$(go run ./cmd/gotosocial/... --db-address some.db.address debug config)"
|
||||
if [ "${TEST_2}" != "${TEST_2_EXPECTED}" ]; then
|
||||
echo "TEST_2 not equal TEST_2_EXPECTED"
|
||||
|
@ -25,7 +25,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_3 Override db-address from default using env var."
|
||||
TEST_3_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_3_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_3="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... debug config)"
|
||||
if [ "${TEST_3}" != "${TEST_3_EXPECTED}" ]; then
|
||||
echo "TEST_3 not equal TEST_3_EXPECTED"
|
||||
|
@ -35,7 +35,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_4 Override db-address from default using both env var and cli flag. The cli flag should take priority."
|
||||
TEST_4_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.other.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_4_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"","db-address":"some.other.db.address","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_4="$(GTS_DB_ADDRESS=some.db.address go run ./cmd/gotosocial/... --db-address some.other.db.address debug config)"
|
||||
if [ "${TEST_4}" != "${TEST_4_EXPECTED}" ]; then
|
||||
echo "TEST_4 not equal TEST_4_EXPECTED"
|
||||
|
@ -45,7 +45,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_5 Test loading a config file by passing an env var."
|
||||
TEST_5_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_5_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_5="$(GTS_CONFIG_PATH=./test/test.yaml go run ./cmd/gotosocial/... debug config)"
|
||||
if [ "${TEST_5}" != "${TEST_5_EXPECTED}" ]; then
|
||||
echo "TEST_5 not equal TEST_5_EXPECTED"
|
||||
|
@ -55,7 +55,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_6 Test loading a config file by passing cli flag."
|
||||
TEST_6_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_6_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_6="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)"
|
||||
if [ "${TEST_6}" != "${TEST_6_EXPECTED}" ]; then
|
||||
echo "TEST_6 not equal TEST_6_EXPECTED"
|
||||
|
@ -65,7 +65,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_7 Test loading a config file and overriding one of the variables with a cli flag."
|
||||
TEST_7_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_7_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_7="$(go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)"
|
||||
if [ "${TEST_7}" != "${TEST_7_EXPECTED}" ]; then
|
||||
echo "TEST_7 not equal TEST_7_EXPECTED"
|
||||
|
@ -75,7 +75,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_8 Test loading a config file and overriding one of the variables with an env var."
|
||||
TEST_8_EXPECTED='{"account-domain":"peepee","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_8_EXPECTED='{"account-domain":"peepee","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_8="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml debug config)"
|
||||
if [ "${TEST_8}" != "${TEST_8_EXPECTED}" ]; then
|
||||
echo "TEST_8 not equal TEST_8_EXPECTED"
|
||||
|
@ -85,7 +85,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_9 Test loading a config file and overriding one of the variables with both an env var and a cli flag. The cli flag should have priority."
|
||||
TEST_9_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_9_EXPECTED='{"account-domain":"","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.yaml","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_9="$(GTS_ACCOUNT_DOMAIN='peepee' go run ./cmd/gotosocial/... --config-path ./test/test.yaml --account-domain '' debug config)"
|
||||
if [ "${TEST_9}" != "${TEST_9_EXPECTED}" ]; then
|
||||
echo "TEST_9 not equal TEST_9_EXPECTED"
|
||||
|
@ -95,7 +95,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_10 Test loading a config file from json."
|
||||
TEST_10_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.json","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","help":false,"host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_10_EXPECTED='{"account-domain":"example.org","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test.json","db-address":"127.0.0.1","db-database":"postgres","db-password":"postgres","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"postgres","email":"","host":"gts.example.org","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":true,"letsencrypt-port":80,"log-db-queries":false,"log-level":"info","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","email","profile","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"someone@example.org","smtp-host":"verycoolemailhost.mail","smtp-password":"smtp-password","smtp-port":8888,"smtp-username":"smtp-username","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32","0.0.0.0/0"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_10="$(go run ./cmd/gotosocial/... --config-path ./test/test.json debug config)"
|
||||
if [ "${TEST_10}" != "${TEST_10_EXPECTED}" ]; then
|
||||
echo "TEST_10 not equal TEST_10_EXPECTED"
|
||||
|
@ -105,7 +105,7 @@ else
|
|||
fi
|
||||
|
||||
echo "TEST_11 Test loading a partial config file. Default values should be used apart from those set in the config file."
|
||||
TEST_11_EXPECTED='{"account-domain":"peepee.poopoo","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test2.yaml","db-address":"","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","help":false,"host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"trace","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_11_EXPECTED='{"account-domain":"peepee.poopoo","accounts-approval-required":true,"accounts-reason-required":true,"accounts-registration-open":true,"application-name":"gotosocial","bind-address":"0.0.0.0","config-path":"./test/test2.yaml","db-address":"","db-database":"gotosocial","db-password":"","db-port":5432,"db-tls-ca-cert":"","db-tls-mode":"disable","db-type":"postgres","db-user":"","email":"","host":"","letsencrypt-cert-dir":"/gotosocial/storage/certs","letsencrypt-email-address":"","letsencrypt-enabled":false,"letsencrypt-port":80,"log-db-queries":false,"log-level":"trace","media-description-max-chars":500,"media-description-min-chars":0,"media-image-max-size":2097152,"media-remote-cache-days":30,"media-video-max-size":10485760,"oidc-client-id":"","oidc-client-secret":"","oidc-enabled":false,"oidc-idp-name":"","oidc-issuer":"","oidc-scopes":["openid","profile","email","groups"],"oidc-skip-verification":false,"password":"","path":"","port":8080,"protocol":"https","smtp-from":"GoToSocial","smtp-host":"","smtp-password":"","smtp-port":0,"smtp-username":"","software-version":"","statuses-cw-max-chars":100,"statuses-max-chars":5000,"statuses-media-max-files":6,"statuses-poll-max-options":6,"statuses-poll-option-max-chars":50,"storage-backend":"local","storage-local-base-path":"/gotosocial/storage","syslog-address":"localhost:514","syslog-enabled":false,"syslog-protocol":"udp","trusted-proxies":["127.0.0.1/32"],"username":"","web-asset-base-dir":"./web/assets/","web-template-base-dir":"./web/template/"}'
|
||||
TEST_11="$(go run ./cmd/gotosocial/... --config-path ./test/test2.yaml debug config)"
|
||||
if [ "${TEST_11}" != "${TEST_11_EXPECTED}" ]; then
|
||||
echo "TEST_11 not equal TEST_11_EXPECTED"
|
||||
|
|
|
@ -19,45 +19,19 @@
|
|||
package testrig
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/coreos/go-oidc/v3/oidc"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
)
|
||||
|
||||
// InitTestConfig resets + initializes the viper configuration with test defaults.
|
||||
// InitTestConfig initializes viper configuration with test defaults.
|
||||
func InitTestConfig() {
|
||||
// reset viper to an empty state
|
||||
viper.Reset()
|
||||
|
||||
// get the field names of config.Keys
|
||||
keyFields := reflect.VisibleFields(reflect.TypeOf(config.Keys))
|
||||
|
||||
// get the field values of config.Keys
|
||||
keyValues := reflect.ValueOf(config.Keys)
|
||||
|
||||
// get the field values of TestDefaults
|
||||
testDefaults := reflect.ValueOf(TestDefaults)
|
||||
|
||||
// for each config field...
|
||||
for _, field := range keyFields {
|
||||
// the viper config key should be the value of the key
|
||||
key, ok := keyValues.FieldByName(field.Name).Interface().(string)
|
||||
if !ok {
|
||||
panic("could not convert config.Keys value to string")
|
||||
}
|
||||
|
||||
// the value should be the test default corresponding to the given fieldName
|
||||
value := testDefaults.FieldByName(field.Name).Interface()
|
||||
|
||||
// actually set the value in viper -- this will override everything
|
||||
viper.Set(key, value)
|
||||
}
|
||||
config.Config(func(cfg *config.Configuration) {
|
||||
*cfg = TestDefaults
|
||||
})
|
||||
}
|
||||
|
||||
// TestDefaults returns a Values struct with values set that are suitable for local testing.
|
||||
var TestDefaults = config.Values{
|
||||
var TestDefaults = config.Configuration{
|
||||
LogLevel: "trace",
|
||||
LogDbQueries: true,
|
||||
ApplicationName: "gotosocial",
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
"strconv"
|
||||
|
||||
"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/db/bundb"
|
||||
|
@ -69,11 +68,15 @@ var testModels = []interface{}{
|
|||
// value as the port instead.
|
||||
func NewTestDB() db.DB {
|
||||
if alternateAddress := os.Getenv("GTS_DB_ADDRESS"); alternateAddress != "" {
|
||||
viper.Set(config.Keys.DbAddress, alternateAddress)
|
||||
config.Config(func(cfg *config.Configuration) {
|
||||
cfg.DbAddress = alternateAddress
|
||||
})
|
||||
}
|
||||
|
||||
if alternateDBType := os.Getenv("GTS_DB_TYPE"); alternateDBType != "" {
|
||||
viper.Set(config.Keys.DbType, alternateDBType)
|
||||
config.Config(func(cfg *config.Configuration) {
|
||||
cfg.DbType = alternateDBType
|
||||
})
|
||||
}
|
||||
|
||||
if alternateDBPort := os.Getenv("GTS_DB_PORT"); alternateDBPort != "" {
|
||||
|
@ -81,7 +84,9 @@ func NewTestDB() db.DB {
|
|||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
viper.Set(config.Keys.DbPort, port)
|
||||
config.Config(func(cfg *config.Configuration) {
|
||||
cfg.DbPort = int(port)
|
||||
})
|
||||
}
|
||||
|
||||
testDB, err := bundb.NewBunDBService(context.Background())
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
package testrig
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/email"
|
||||
)
|
||||
|
@ -30,7 +29,9 @@ import (
|
|||
// the map, with email address of the recipient as the key, and the value as the
|
||||
// parsed email message as it would have been sent.
|
||||
func NewEmailSender(templateBaseDir string, sentEmails map[string]string) email.Sender {
|
||||
viper.Set(config.Keys.WebTemplateBaseDir, templateBaseDir)
|
||||
config.Config(func(cfg *config.Configuration) {
|
||||
cfg.WebTemplateBaseDir = templateBaseDir
|
||||
})
|
||||
|
||||
var sendCallback func(toAddress string, message string)
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@ import (
|
|||
"runtime"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/config"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/db"
|
||||
"github.com/superseriousbusiness/gotosocial/internal/router"
|
||||
|
@ -38,11 +37,13 @@ import (
|
|||
// value as the template base directory instead.
|
||||
func NewTestRouter(db db.DB) router.Router {
|
||||
if alternativeTemplateBaseDir := os.Getenv("GTS_WEB_TEMPLATE_BASE_DIR"); alternativeTemplateBaseDir != "" {
|
||||
viper.Set(config.Keys.WebTemplateBaseDir, alternativeTemplateBaseDir)
|
||||
config.Config(func(cfg *config.Configuration) {
|
||||
cfg.WebTemplateBaseDir = alternativeTemplateBaseDir
|
||||
})
|
||||
}
|
||||
|
||||
if alternativeBindAddress := os.Getenv("GTS_BIND_ADDRESS"); alternativeBindAddress != "" {
|
||||
viper.Set(config.Keys.BindAddress, alternativeBindAddress)
|
||||
config.SetBindAddress(alternativeBindAddress)
|
||||
}
|
||||
|
||||
r, err := router.New(context.Background(), db)
|
||||
|
@ -56,7 +57,7 @@ func NewTestRouter(db db.DB) router.Router {
|
|||
func ConfigureTemplatesWithGin(engine *gin.Engine) {
|
||||
router.LoadTemplateFunctions(engine)
|
||||
|
||||
templateBaseDir := viper.GetString(config.Keys.WebTemplateBaseDir)
|
||||
templateBaseDir := config.GetWebTemplateBaseDir()
|
||||
|
||||
if !filepath.IsAbs(templateBaseDir) {
|
||||
// https://stackoverflow.com/questions/31873396/is-it-possible-to-get-the-current-root-of-package-structure-as-a-string-in-golan
|
||||
|
|
Loading…
Reference in a new issue