summaryrefslogtreecommitdiff
path: root/cmd/gotosocial
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/gotosocial')
-rw-r--r--cmd/gotosocial/accountsflags.go47
-rw-r--r--cmd/gotosocial/action/action.go (renamed from cmd/gotosocial/commands.go)21
-rw-r--r--cmd/gotosocial/action/admin/account/account.go258
-rw-r--r--cmd/gotosocial/action/admin/trans/export.go52
-rw-r--r--cmd/gotosocial/action/admin/trans/import.go52
-rw-r--r--cmd/gotosocial/action/debug/config/config.go (renamed from cmd/gotosocial/testrigcommands.go)33
-rw-r--r--cmd/gotosocial/action/server/server.go225
-rw-r--r--cmd/gotosocial/action/testrig/testrig.go184
-rw-r--r--cmd/gotosocial/admin.go169
-rw-r--r--cmd/gotosocial/admincommands.go184
-rw-r--r--cmd/gotosocial/common.go64
-rw-r--r--cmd/gotosocial/databaseflags.go77
-rw-r--r--cmd/gotosocial/debug.go (renamed from cmd/gotosocial/flags.go)41
-rw-r--r--cmd/gotosocial/flag/admin.go62
-rw-r--r--cmd/gotosocial/flag/global.go45
-rw-r--r--cmd/gotosocial/flag/server.go111
-rw-r--r--cmd/gotosocial/flag/usage.go80
-rw-r--r--cmd/gotosocial/generalflags.go84
-rw-r--r--cmd/gotosocial/letsencryptflags.go53
-rw-r--r--cmd/gotosocial/main.go49
-rw-r--r--cmd/gotosocial/mediaflags.go53
-rw-r--r--cmd/gotosocial/oidcflags.go71
-rw-r--r--cmd/gotosocial/runaction.go82
-rw-r--r--cmd/gotosocial/server.go (renamed from cmd/gotosocial/templateflags.go)34
-rw-r--r--cmd/gotosocial/smtpflags.go59
-rw-r--r--cmd/gotosocial/statusesflags.go59
-rw-r--r--cmd/gotosocial/storageflags.go59
-rw-r--r--cmd/gotosocial/testrig.go (renamed from cmd/gotosocial/servercommands.go)32
28 files changed, 1415 insertions, 925 deletions
diff --git a/cmd/gotosocial/accountsflags.go b/cmd/gotosocial/accountsflags.go
deleted file mode 100644
index 9f9be266d..000000000
--- a/cmd/gotosocial/accountsflags.go
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func accountsFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.BoolFlag{
- Name: flagNames.AccountsOpenRegistration,
- Usage: "Allow anyone to submit an account signup request. If false, server will be invite-only.",
- Value: defaults.AccountsOpenRegistration,
- EnvVars: []string{envNames.AccountsOpenRegistration},
- },
- &cli.BoolFlag{
- Name: flagNames.AccountsApprovalRequired,
- Usage: "Do account signups require approval by an admin or moderator before user can log in? If false, new registrations will be automatically approved.",
- Value: defaults.AccountsRequireApproval,
- EnvVars: []string{envNames.AccountsApprovalRequired},
- },
- &cli.BoolFlag{
- Name: flagNames.AccountsReasonRequired,
- Usage: "Do new account signups require a reason to be submitted on registration?",
- Value: defaults.AccountsReasonRequired,
- EnvVars: []string{envNames.AccountsReasonRequired},
- },
- }
-}
diff --git a/cmd/gotosocial/commands.go b/cmd/gotosocial/action/action.go
index 9b61a66ec..315b30de6 100644
--- a/cmd/gotosocial/commands.go
+++ b/cmd/gotosocial/action/action.go
@@ -16,22 +16,13 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package main
+package action
import (
- "github.com/urfave/cli/v2"
+ "context"
)
-func getCommands(allFlags []cli.Flag) []*cli.Command {
- commands := []*cli.Command{}
- commandSets := [][]*cli.Command{
- serverCommands(allFlags),
- adminCommands(allFlags),
- testrigCommands(allFlags),
- }
- for _, cs := range commandSets {
- commands = append(commands, cs...)
- }
-
- return commands
-}
+// GTSAction defines one *action* that can be taken by the gotosocial cli command.
+// This can be either a long-running action (like server start) or something
+// shorter like db init or db inspect.
+type GTSAction func(context.Context) error
diff --git a/cmd/gotosocial/action/admin/account/account.go b/cmd/gotosocial/action/admin/account/account.go
new file mode 100644
index 000000000..6b1029712
--- /dev/null
+++ b/cmd/gotosocial/action/admin/account/account.go
@@ -0,0 +1,258 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package account
+
+import (
+ "context"
+ "errors"
+ "fmt"
+ "time"
+
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
+ "github.com/superseriousbusiness/gotosocial/internal/db"
+ "github.com/superseriousbusiness/gotosocial/internal/db/bundb"
+ "github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
+ "github.com/superseriousbusiness/gotosocial/internal/validate"
+ "golang.org/x/crypto/bcrypt"
+)
+
+// Create creates a new account in the database using the provided flags.
+var Create action.GTSAction = func(ctx context.Context) error {
+ dbConn, err := bundb.NewBunDBService(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ username := viper.GetString(config.Keys.AdminAccountUsername)
+ if username == "" {
+ return errors.New("no username set")
+ }
+ if err := validate.Username(username); err != nil {
+ return err
+ }
+
+ email := viper.GetString(config.Keys.AdminAccountEmail)
+ if email == "" {
+ return errors.New("no email set")
+ }
+ if err := validate.Email(email); err != nil {
+ return err
+ }
+
+ password := viper.GetString(config.Keys.AdminAccountPassword)
+ if password == "" {
+ return errors.New("no password set")
+ }
+ if err := validate.NewPassword(password); err != nil {
+ return err
+ }
+
+ _, err = dbConn.NewSignup(ctx, username, "", false, email, password, nil, "", "", false, false)
+ if err != nil {
+ return err
+ }
+
+ return dbConn.Stop(ctx)
+}
+
+// Confirm sets a user to Approved, sets Email to the current UnconfirmedEmail value, and sets ConfirmedAt to now.
+var Confirm action.GTSAction = func(ctx context.Context) error {
+ dbConn, err := bundb.NewBunDBService(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ username := viper.GetString(config.Keys.AdminAccountUsername)
+ if username == "" {
+ return errors.New("no username set")
+ }
+ if err := validate.Username(username); err != nil {
+ return err
+ }
+
+ a, err := dbConn.GetLocalAccountByUsername(ctx, username)
+ if err != nil {
+ return err
+ }
+
+ u := &gtsmodel.User{}
+ if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
+ return err
+ }
+
+ u.Approved = true
+ u.Email = u.UnconfirmedEmail
+ u.ConfirmedAt = time.Now()
+ if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
+ return err
+ }
+
+ return dbConn.Stop(ctx)
+}
+
+// Promote sets a user to admin.
+var Promote action.GTSAction = func(ctx context.Context) error {
+ dbConn, err := bundb.NewBunDBService(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ username := viper.GetString(config.Keys.AdminAccountUsername)
+ if username == "" {
+ return errors.New("no username set")
+ }
+ if err := validate.Username(username); err != nil {
+ return err
+ }
+
+ a, err := dbConn.GetLocalAccountByUsername(ctx, username)
+ if err != nil {
+ return err
+ }
+
+ u := &gtsmodel.User{}
+ if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
+ return err
+ }
+ u.Admin = true
+ if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
+ return err
+ }
+
+ return dbConn.Stop(ctx)
+}
+
+// Demote sets admin on a user to false.
+var Demote action.GTSAction = func(ctx context.Context) error {
+ dbConn, err := bundb.NewBunDBService(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ username := viper.GetString(config.Keys.AdminAccountUsername)
+ if username == "" {
+ return errors.New("no username set")
+ }
+ if err := validate.Username(username); err != nil {
+ return err
+ }
+
+ a, err := dbConn.GetLocalAccountByUsername(ctx, username)
+ if err != nil {
+ return err
+ }
+
+ u := &gtsmodel.User{}
+ if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
+ return err
+ }
+ u.Admin = false
+ if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
+ return err
+ }
+
+ return dbConn.Stop(ctx)
+}
+
+// Disable sets Disabled to true on a user.
+var Disable action.GTSAction = func(ctx context.Context) error {
+ dbConn, err := bundb.NewBunDBService(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ username := viper.GetString(config.Keys.AdminAccountUsername)
+ if username == "" {
+ return errors.New("no username set")
+ }
+ if err := validate.Username(username); err != nil {
+ return err
+ }
+
+ a, err := dbConn.GetLocalAccountByUsername(ctx, username)
+ if err != nil {
+ return err
+ }
+
+ u := &gtsmodel.User{}
+ if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
+ return err
+ }
+ u.Disabled = true
+ if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
+ return err
+ }
+
+ return dbConn.Stop(ctx)
+}
+
+// Suspend suspends the target account, cleanly removing all of its media, followers, following, likes, statuses, etc.
+var Suspend action.GTSAction = func(ctx context.Context) error {
+ // TODO
+ return nil
+}
+
+// Password sets the password of target account.
+var Password action.GTSAction = func(ctx context.Context) error {
+ dbConn, err := bundb.NewBunDBService(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ username := viper.GetString(config.Keys.AdminAccountUsername)
+ if username == "" {
+ return errors.New("no username set")
+ }
+ if err := validate.Username(username); err != nil {
+ return err
+ }
+
+ password := viper.GetString(config.Keys.AdminAccountPassword)
+ if password == "" {
+ return errors.New("no password set")
+ }
+ if err := validate.NewPassword(password); err != nil {
+ return err
+ }
+
+ a, err := dbConn.GetLocalAccountByUsername(ctx, username)
+ if err != nil {
+ return err
+ }
+
+ u := &gtsmodel.User{}
+ if err := dbConn.GetWhere(ctx, []db.Where{{Key: "account_id", Value: a.ID}}, u); err != nil {
+ return err
+ }
+
+ pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
+ if err != nil {
+ return fmt.Errorf("error hashing password: %s", err)
+ }
+
+ u.EncryptedPassword = string(pw)
+
+ if err := dbConn.UpdateByPrimaryKey(ctx, u); err != nil {
+ return err
+ }
+
+ return nil
+}
diff --git a/cmd/gotosocial/action/admin/trans/export.go b/cmd/gotosocial/action/admin/trans/export.go
new file mode 100644
index 000000000..615ba72f0
--- /dev/null
+++ b/cmd/gotosocial/action/admin/trans/export.go
@@ -0,0 +1,52 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package trans
+
+import (
+ "context"
+ "errors"
+ "fmt"
+
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
+ "github.com/superseriousbusiness/gotosocial/internal/db/bundb"
+ "github.com/superseriousbusiness/gotosocial/internal/trans"
+)
+
+// Export exports info from the database into a file
+var Export action.GTSAction = func(ctx context.Context) error {
+ dbConn, err := bundb.NewBunDBService(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ exporter := trans.NewExporter(dbConn)
+
+ path := viper.GetString(config.Keys.AdminTransPath)
+ if path == "" {
+ return errors.New("no path set")
+ }
+
+ if err := exporter.ExportMinimal(ctx, path); err != nil {
+ return err
+ }
+
+ return dbConn.Stop(ctx)
+}
diff --git a/cmd/gotosocial/action/admin/trans/import.go b/cmd/gotosocial/action/admin/trans/import.go
new file mode 100644
index 000000000..688083130
--- /dev/null
+++ b/cmd/gotosocial/action/admin/trans/import.go
@@ -0,0 +1,52 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package trans
+
+import (
+ "context"
+ "errors"
+ "fmt"
+
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
+ "github.com/superseriousbusiness/gotosocial/internal/db/bundb"
+ "github.com/superseriousbusiness/gotosocial/internal/trans"
+)
+
+// Import imports info from a file into the database
+var Import action.GTSAction = func(ctx context.Context) error {
+ dbConn, err := bundb.NewBunDBService(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ importer := trans.NewImporter(dbConn)
+
+ path := viper.GetString(config.Keys.AdminTransPath)
+ if path == "" {
+ return errors.New("no path set")
+ }
+
+ if err := importer.Import(ctx, path); err != nil {
+ return err
+ }
+
+ return dbConn.Stop(ctx)
+}
diff --git a/cmd/gotosocial/testrigcommands.go b/cmd/gotosocial/action/debug/config/config.go
index aabe04267..749ea124d 100644
--- a/cmd/gotosocial/testrigcommands.go
+++ b/cmd/gotosocial/action/debug/config/config.go
@@ -16,27 +16,24 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-package main
+package config
import (
- "github.com/superseriousbusiness/gotosocial/internal/cliactions/testrig"
- "github.com/urfave/cli/v2"
+ "context"
+ "encoding/json"
+ "fmt"
+
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
)
-func testrigCommands(allFlags []cli.Flag) []*cli.Command {
- return []*cli.Command{
- {
- Name: "testrig",
- Usage: "gotosocial testrig tasks",
- Subcommands: []*cli.Command{
- {
- Name: "start",
- Usage: "start the gotosocial testrig",
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, testrig.Start)
- },
- },
- },
- },
+// 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)
+ if err != nil {
+ return err
}
+ fmt.Println(string(b))
+ return nil
}
diff --git a/cmd/gotosocial/action/server/server.go b/cmd/gotosocial/action/server/server.go
new file mode 100644
index 000000000..57384ac6f
--- /dev/null
+++ b/cmd/gotosocial/action/server/server.go
@@ -0,0 +1,225 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package server
+
+import (
+ "context"
+ "fmt"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+
+ "codeberg.org/gruf/go-store/kv"
+ "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"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/admin"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/app"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/auth"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/blocks"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/emoji"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/favourites"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/fileserver"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/filter"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/followrequest"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/instance"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/list"
+ mediaModule "github.com/superseriousbusiness/gotosocial/internal/api/client/media"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/notification"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/search"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/status"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/streaming"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/timeline"
+ userClient "github.com/superseriousbusiness/gotosocial/internal/api/client/user"
+ "github.com/superseriousbusiness/gotosocial/internal/api/s2s/nodeinfo"
+ "github.com/superseriousbusiness/gotosocial/internal/api/s2s/user"
+ "github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger"
+ "github.com/superseriousbusiness/gotosocial/internal/api/security"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
+ "github.com/superseriousbusiness/gotosocial/internal/db/bundb"
+ "github.com/superseriousbusiness/gotosocial/internal/email"
+ "github.com/superseriousbusiness/gotosocial/internal/federation"
+ "github.com/superseriousbusiness/gotosocial/internal/federation/federatingdb"
+ "github.com/superseriousbusiness/gotosocial/internal/gotosocial"
+ "github.com/superseriousbusiness/gotosocial/internal/media"
+ "github.com/superseriousbusiness/gotosocial/internal/oauth"
+ "github.com/superseriousbusiness/gotosocial/internal/oidc"
+ "github.com/superseriousbusiness/gotosocial/internal/processing"
+ "github.com/superseriousbusiness/gotosocial/internal/router"
+ timelineprocessing "github.com/superseriousbusiness/gotosocial/internal/timeline"
+ "github.com/superseriousbusiness/gotosocial/internal/transport"
+ "github.com/superseriousbusiness/gotosocial/internal/typeutils"
+ "github.com/superseriousbusiness/gotosocial/internal/web"
+)
+
+// Start creates and starts a gotosocial server
+var Start action.GTSAction = func(ctx context.Context) error {
+ dbService, err := bundb.NewBunDBService(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ if err := dbService.CreateInstanceAccount(ctx); err != nil {
+ return fmt.Errorf("error creating instance account: %s", err)
+ }
+
+ if err := dbService.CreateInstanceInstance(ctx); err != nil {
+ return fmt.Errorf("error creating instance instance: %s", err)
+ }
+
+ federatingDB := federatingdb.New(dbService)
+
+ router, err := router.New(ctx, dbService)
+ if err != nil {
+ return fmt.Errorf("error creating router: %s", err)
+ }
+
+ // build converters and util
+ typeConverter := typeutils.NewConverter(dbService)
+ timelineManager := timelineprocessing.NewManager(dbService, typeConverter)
+
+ // Open the storage backend
+ storageBasePath := viper.GetString(config.Keys.StorageBasePath)
+ storage, err := kv.OpenFile(storageBasePath, nil)
+ if err != nil {
+ return fmt.Errorf("error creating storage backend: %s", err)
+ }
+
+ // build backend handlers
+ mediaHandler := media.New(dbService, storage)
+ oauthServer := oauth.New(ctx, dbService)
+ transportController := transport.NewController(dbService, &federation.Clock{}, http.DefaultClient)
+ federator := federation.NewFederator(dbService, federatingDB, transportController, typeConverter, mediaHandler)
+
+ // 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 != "" {
+ // host is defined so create a proper sender
+ emailSender, err = email.NewSender()
+ if err != nil {
+ return fmt.Errorf("error creating email sender: %s", err)
+ }
+ } else {
+ // no host is defined so create a noop sender
+ emailSender, err = email.NewNoopSender(nil)
+ if err != nil {
+ return fmt.Errorf("error creating noop email sender: %s", err)
+ }
+ }
+
+ // create and start the message processor using the other services we've created so far
+ processor := processing.NewProcessor(typeConverter, federator, oauthServer, mediaHandler, storage, timelineManager, dbService, emailSender)
+ if err := processor.Start(ctx); err != nil {
+ return fmt.Errorf("error starting processor: %s", err)
+ }
+
+ idp, err := oidc.NewIDP(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating oidc idp: %s", err)
+ }
+
+ // build client api modules
+ authModule := auth.New(dbService, oauthServer, idp)
+ accountModule := account.New(processor)
+ instanceModule := instance.New(processor)
+ appsModule := app.New(processor)
+ followRequestsModule := followrequest.New(processor)
+ webfingerModule := webfinger.New(processor)
+ nodeInfoModule := nodeinfo.New(processor)
+ webBaseModule := web.New(processor)
+ usersModule := user.New(processor)
+ timelineModule := timeline.New(processor)
+ notificationModule := notification.New(processor)
+ searchModule := search.New(processor)
+ filtersModule := filter.New(processor)
+ emojiModule := emoji.New(processor)
+ listsModule := list.New(processor)
+ mm := mediaModule.New(processor)
+ fileServerModule := fileserver.New(processor)
+ adminModule := admin.New(processor)
+ statusModule := status.New(processor)
+ securityModule := security.New(dbService, oauthServer)
+ streamingModule := streaming.New(processor)
+ favouritesModule := favourites.New(processor)
+ blocksModule := blocks.New(processor)
+ userClientModule := userClient.New(processor)
+
+ apis := []api.ClientModule{
+ // modules with middleware go first
+ securityModule,
+ authModule,
+
+ // now everything else
+ webBaseModule,
+ accountModule,
+ instanceModule,
+ appsModule,
+ followRequestsModule,
+ mm,
+ fileServerModule,
+ adminModule,
+ statusModule,
+ webfingerModule,
+ nodeInfoModule,
+ usersModule,
+ timelineModule,
+ notificationModule,
+ searchModule,
+ filtersModule,
+ emojiModule,
+ listsModule,
+ streamingModule,
+ favouritesModule,
+ blocksModule,
+ userClientModule,
+ }
+
+ for _, m := range apis {
+ if err := m.Route(router); err != nil {
+ return fmt.Errorf("routing error: %s", err)
+ }
+ }
+
+ gts, err := gotosocial.NewServer(dbService, router, federator)
+ if err != nil {
+ return fmt.Errorf("error creating gotosocial service: %s", err)
+ }
+
+ if err := gts.Start(ctx); err != nil {
+ return fmt.Errorf("error starting gotosocial service: %s", err)
+ }
+
+ // catch shutdown signals from the operating system
+ sigs := make(chan os.Signal, 1)
+ signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
+ sig := <-sigs
+ logrus.Infof("received signal %s, shutting down", sig)
+
+ // close down all running services in order
+ if err := gts.Stop(ctx); err != nil {
+ return fmt.Errorf("error closing gotosocial service: %s", err)
+ }
+
+ logrus.Info("done! exiting...")
+ return nil
+}
diff --git a/cmd/gotosocial/action/testrig/testrig.go b/cmd/gotosocial/action/testrig/testrig.go
new file mode 100644
index 000000000..626a22781
--- /dev/null
+++ b/cmd/gotosocial/action/testrig/testrig.go
@@ -0,0 +1,184 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package testrig
+
+import (
+ "bytes"
+ "context"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+
+ "github.com/sirupsen/logrus"
+ "github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
+ "github.com/superseriousbusiness/gotosocial/internal/api"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/account"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/admin"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/app"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/auth"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/blocks"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/emoji"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/favourites"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/fileserver"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/filter"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/followrequest"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/instance"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/list"
+ mediaModule "github.com/superseriousbusiness/gotosocial/internal/api/client/media"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/notification"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/search"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/status"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/streaming"
+ "github.com/superseriousbusiness/gotosocial/internal/api/client/timeline"
+ userClient "github.com/superseriousbusiness/gotosocial/internal/api/client/user"
+ "github.com/superseriousbusiness/gotosocial/internal/api/s2s/nodeinfo"
+ "github.com/superseriousbusiness/gotosocial/internal/api/s2s/user"
+ "github.com/superseriousbusiness/gotosocial/internal/api/s2s/webfinger"
+ "github.com/superseriousbusiness/gotosocial/internal/api/security"
+ "github.com/superseriousbusiness/gotosocial/internal/gotosocial"
+ "github.com/superseriousbusiness/gotosocial/internal/oidc"
+ "github.com/superseriousbusiness/gotosocial/internal/web"
+ "github.com/superseriousbusiness/gotosocial/testrig"
+)
+
+// Start creates and starts a gotosocial testrig server
+var Start action.GTSAction = func(ctx context.Context) error {
+ testrig.InitTestConfig()
+ testrig.InitTestLog()
+
+ dbService := testrig.NewTestDB()
+ testrig.StandardDBSetup(dbService, nil)
+ router := testrig.NewTestRouter(dbService)
+ storageBackend := testrig.NewTestStorage()
+ testrig.StandardStorageSetup(storageBackend, "./testrig/media")
+
+ // build backend handlers
+ oauthServer := testrig.NewTestOauthServer(dbService)
+ transportController := testrig.NewTestTransportController(testrig.NewMockHTTPClient(func(req *http.Request) (*http.Response, error) {
+ r := ioutil.NopCloser(bytes.NewReader([]byte{}))
+ return &http.Response{
+ StatusCode: 200,
+ Body: r,
+ }, nil
+ }), dbService)
+ federator := testrig.NewTestFederator(dbService, transportController, storageBackend)
+
+ emailSender := testrig.NewEmailSender("./web/template/", nil)
+
+ processor := testrig.NewTestProcessor(dbService, storageBackend, federator, emailSender)
+ if err := processor.Start(ctx); err != nil {
+ return fmt.Errorf("error starting processor: %s", err)
+ }
+
+ idp, err := oidc.NewIDP(ctx)
+ if err != nil {
+ return fmt.Errorf("error creating oidc idp: %s", err)
+ }
+
+ // build client api modules
+ authModule := auth.New(dbService, oauthServer, idp)
+ accountModule := account.New(processor)
+ instanceModule := instance.New(processor)
+ appsModule := app.New(processor)
+ followRequestsModule := followrequest.New(processor)
+ webfingerModule := webfinger.New(processor)
+ nodeInfoModule := nodeinfo.New(processor)
+ webBaseModule := web.New(processor)
+ usersModule := user.New(processor)
+ timelineModule := timeline.New(processor)
+ notificationModule := notification.New(processor)
+ searchModule := search.New(processor)
+ filtersModule := filter.New(processor)
+ emojiModule := emoji.New(processor)
+ listsModule := list.New(processor)
+ mm := mediaModule.New(processor)
+ fileServerModule := fileserver.New(processor)
+ adminModule := admin.New(processor)
+ statusModule := status.New(processor)
+ securityModule := security.New(dbService, oauthServer)
+ streamingModule := streaming.New(processor)
+ favouritesModule := favourites.New(processor)
+ blocksModule := blocks.New(processor)
+ userClientModule := userClient.New(processor)
+
+ apis := []api.ClientModule{
+ // modules with middleware go first
+ securityModule,
+ authModule,
+
+ // now everything else
+ webBaseModule,
+ accountModule,
+ instanceModule,
+ appsModule,
+ followRequestsModule,
+ mm,
+ fileServerModule,
+ adminModule,
+ statusModule,
+ webfingerModule,
+ nodeInfoModule,
+ usersModule,
+ timelineModule,
+ notificationModule,
+ searchModule,
+ filtersModule,
+ emojiModule,
+ listsModule,
+ streamingModule,
+ favouritesModule,
+ blocksModule,
+ userClientModule,
+ }
+
+ for _, m := range apis {
+ if err := m.Route(router); err != nil {
+ return fmt.Errorf("routing error: %s", err)
+ }
+ }
+
+ gts, err := gotosocial.NewServer(dbService, router, federator)
+ if err != nil {
+ return fmt.Errorf("error creating gotosocial service: %s", err)
+ }
+
+ if err := gts.Start(ctx); err != nil {
+ return fmt.Errorf("error starting gotosocial service: %s", err)
+ }
+
+ // catch shutdown signals from the operating system
+ sigs := make(chan os.Signal, 1)
+ signal.Notify(sigs, os.Interrupt, syscall.SIGTERM)
+ sig := <-sigs
+ logrus.Infof("received signal %s, shutting down", sig)
+
+ testrig.StandardDBTeardown(dbService)
+ testrig.StandardStorageTeardown(storageBackend)
+
+ // close down all running services in order
+ if err := gts.Stop(ctx); err != nil {
+ return fmt.Errorf("error closing gotosocial service: %s", err)
+ }
+
+ logrus.Info("done! exiting...")
+ return nil
+}
diff --git a/cmd/gotosocial/admin.go b/cmd/gotosocial/admin.go
new file mode 100644
index 000000000..9ee4461ea
--- /dev/null
+++ b/cmd/gotosocial/admin.go
@@ -0,0 +1,169 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package main
+
+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"
+)
+
+func adminCommands() *cobra.Command {
+ adminCmd := &cobra.Command{
+ Use: "admin",
+ Short: "gotosocial admin-related tasks",
+ }
+
+ /*
+ ADMIN ACCOUNT COMMANDS
+ */
+
+ adminAccountCmd := &cobra.Command{
+ Use: "account",
+ Short: "admin commands related to accounts",
+ }
+ flag.AdminAccount(adminAccountCmd, config.Defaults)
+
+ adminAccountCreateCmd := &cobra.Command{
+ Use: "create",
+ Short: "create a new account",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), account.Create)
+ },
+ }
+ flag.AdminAccountCreate(adminAccountCreateCmd, config.Defaults)
+ adminAccountCmd.AddCommand(adminAccountCreateCmd)
+
+ adminAccountConfirmCmd := &cobra.Command{
+ Use: "confirm",
+ Short: "confirm an existing account manually, thereby skipping email confirmation",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), account.Confirm)
+ },
+ }
+ flag.AdminAccount(adminAccountConfirmCmd, config.Defaults)
+ adminAccountCmd.AddCommand(adminAccountConfirmCmd)
+
+ adminAccountPromoteCmd := &cobra.Command{
+ Use: "promote",
+ Short: "promote an account to admin",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), account.Promote)
+ },
+ }
+ flag.AdminAccount(adminAccountPromoteCmd, config.Defaults)
+ adminAccountCmd.AddCommand(adminAccountPromoteCmd)
+
+ adminAccountDemoteCmd := &cobra.Command{
+ Use: "demote",
+ Short: "demote an account from admin to normal user",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), account.Demote)
+ },
+ }
+ flag.AdminAccount(adminAccountDemoteCmd, config.Defaults)
+ adminAccountCmd.AddCommand(adminAccountDemoteCmd)
+
+ adminAccountDisableCmd := &cobra.Command{
+ Use: "disable",
+ Short: "prevent an account from signing in or posting etc, but don't delete anything",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), account.Disable)
+ },
+ }
+ flag.AdminAccount(adminAccountDisableCmd, config.Defaults)
+ adminAccountCmd.AddCommand(adminAccountDisableCmd)
+
+ adminAccountSuspendCmd := &cobra.Command{
+ Use: "suspend",
+ Short: "completely remove an account and all of its posts, media, etc",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), account.Suspend)
+ },
+ }
+ flag.AdminAccount(adminAccountSuspendCmd, config.Defaults)
+ adminAccountCmd.AddCommand(adminAccountSuspendCmd)
+
+ adminAccountPasswordCmd := &cobra.Command{
+ Use: "password",
+ Short: "set a new password for the given account",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), account.Password)
+ },
+ }
+ flag.AdminAccountPassword(adminAccountPasswordCmd, config.Defaults)
+ adminAccountCmd.AddCommand(adminAccountPasswordCmd)
+
+ adminCmd.AddCommand(adminAccountCmd)
+
+ /*
+ ADMIN IMPORT/EXPORT COMMANDS
+ */
+
+ adminExportCmd := &cobra.Command{
+ Use: "export",
+ Short: "export data from the database to file at the given path",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), trans.Export)
+ },
+ }
+ flag.AdminTrans(adminExportCmd, config.Defaults)
+ adminCmd.AddCommand(adminExportCmd)
+
+ adminImportCmd := &cobra.Command{
+ Use: "import",
+ Short: "import data from a file into the database",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), trans.Import)
+ },
+ }
+ flag.AdminTrans(adminImportCmd, config.Defaults)
+ adminCmd.AddCommand(adminImportCmd)
+
+ return adminCmd
+}
diff --git a/cmd/gotosocial/admincommands.go b/cmd/gotosocial/admincommands.go
deleted file mode 100644
index a70693b2c..000000000
--- a/cmd/gotosocial/admincommands.go
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/cliactions/admin/account"
- "github.com/superseriousbusiness/gotosocial/internal/cliactions/admin/trans"
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func adminCommands(allFlags []cli.Flag) []*cli.Command {
- return []*cli.Command{
- {
- Name: "admin",
- Usage: "gotosocial admin-related tasks",
- Subcommands: []*cli.Command{
- {
- Name: "account",
- Usage: "admin commands related to accounts",
- Subcommands: []*cli.Command{
- {
- Name: "create",
- Usage: "create a new account",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: config.UsernameFlag,
- Usage: config.UsernameUsage,
- Required: true,
- },
- &cli.StringFlag{
- Name: config.EmailFlag,
- Usage: config.EmailUsage,
- Required: true,
- },
- &cli.StringFlag{
- Name: config.PasswordFlag,
- Usage: config.PasswordUsage,
- Required: true,
- },
- },
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, account.Create)
- },
- },
- {
- Name: "confirm",
- Usage: "confirm an existing account manually, thereby skipping email confirmation",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: config.UsernameFlag,
- Usage: config.UsernameUsage,
- Required: true,
- },
- },
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, account.Confirm)
- },
- },
- {
- Name: "promote",
- Usage: "promote an account to admin",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: config.UsernameFlag,
- Usage: config.UsernameUsage,
- Required: true,
- },
- },
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, account.Promote)
- },
- },
- {
- Name: "demote",
- Usage: "demote an account from admin to normal user",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: config.UsernameFlag,
- Usage: config.UsernameUsage,
- Required: true,
- },
- },
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, account.Demote)
- },
- },
- {
- Name: "disable",
- Usage: "prevent an account from signing in or posting etc, but don't delete anything",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: config.UsernameFlag,
- Usage: config.UsernameUsage,
- Required: true,
- },
- },
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, account.Disable)
- },
- },
- {
- Name: "suspend",
- Usage: "completely remove an account and all of its posts, media, etc",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: config.UsernameFlag,
- Usage: config.UsernameUsage,
- Required: true,
- },
- },
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, account.Suspend)
- },
- },
- {
- Name: "password",
- Usage: "set a new password for the given account",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: config.UsernameFlag,
- Usage: config.UsernameUsage,
- Required: true,
- },
- &cli.StringFlag{
- Name: config.PasswordFlag,
- Usage: config.PasswordUsage,
- Required: true,
- },
- },
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, account.Password)
- },
- },
- },
- },
- {
- Name: "export",
- Usage: "export data from the database to file at the given path",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: config.TransPathFlag,
- Usage: config.TransPathUsage,
- Required: true,
- },
- },
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, trans.Export)
- },
- },
- {
- Name: "import",
- Usage: "import data from a file into the database",
- Flags: []cli.Flag{
- &cli.StringFlag{
- Name: config.TransPathFlag,
- Usage: config.TransPathUsage,
- Required: true,
- },
- },
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, trans.Import)
- },
- },
- },
- },
- }
-}
diff --git a/cmd/gotosocial/common.go b/cmd/gotosocial/common.go
new file mode 100644
index 000000000..7b5a42652
--- /dev/null
+++ b/cmd/gotosocial/common.go
@@ -0,0 +1,64 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package main
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/spf13/cobra"
+ "github.com/spf13/viper"
+ "github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
+ "github.com/superseriousbusiness/gotosocial/internal/log"
+)
+
+// preRun should be run in the pre-run stage of every cobra command.
+// The goal here is to initialize the viper config store, and also read in
+// the config file (if present).
+//
+// The order of these is important: the init-config function reads the location
+// of the config file from the viper store so that it can be picked up by either
+// env vars or cli flag.
+func preRun(cmd *cobra.Command) error {
+ if err := config.InitViper(cmd.Flags()); err != nil {
+ return fmt.Errorf("error initializing viper: %s", err)
+ }
+
+ if err := config.ReadFromFile(); err != nil {
+ return fmt.Errorf("error initializing config: %s", err)
+ }
+
+ return nil
+}
+
+// run should be used during the run stage of every cobra command.
+// The idea here is to take a GTSAction and run it with the given
+// context, after initializing any last-minute things like loggers etc.
+func run(ctx context.Context, action action.GTSAction) error {
+ // if log level has been set...
+ if logLevel := viper.GetString(config.Keys.LogLevel); logLevel != "" {
+ // then try to initialize the logger to that level
+ if err := log.Initialize(logLevel); err != nil {
+ return fmt.Errorf("error initializing log: %s", err)
+ }
+ }
+
+ return action(ctx)
+}
diff --git a/cmd/gotosocial/databaseflags.go b/cmd/gotosocial/databaseflags.go
deleted file mode 100644
index 7abe64f1b..000000000
--- a/cmd/gotosocial/databaseflags.go
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func databaseFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.StringFlag{
- Name: flagNames.DbType,
- Usage: "Database type: eg., postgres",
- Value: defaults.DbType,
- EnvVars: []string{envNames.DbType},
- },
- &cli.StringFlag{
- Name: flagNames.DbAddress,
- Usage: "Database ipv4 address or hostname",
- Value: defaults.DbAddress,
- EnvVars: []string{envNames.DbAddress},
- },
- &cli.IntFlag{
- Name: flagNames.DbPort,
- Usage: "Database port",
- Value: defaults.DbPort,
- EnvVars: []string{envNames.DbPort},
- },
- &cli.StringFlag{
- Name: flagNames.DbUser,
- Usage: "Database username",
- Value: defaults.DbUser,
- EnvVars: []string{envNames.DbUser},
- },
- &cli.StringFlag{
- Name: flagNames.DbPassword,
- Usage: "Database password",
- Value: defaults.DbPassword,
- EnvVars: []string{envNames.DbPassword},
- },
- &cli.StringFlag{
- Name: flagNames.DbDatabase,
- Usage: "Database name",
- Value: defaults.DbDatabase,
- EnvVars: []string{envNames.DbDatabase},
- },
- &cli.StringFlag{
- Name: flagNames.DbTLSMode,
- Usage: "Database tls mode",
- Value: defaults.DBTlsMode,
- EnvVars: []string{envNames.DbTLSMode},
- },
- &cli.StringFlag{
- Name: flagNames.DbTLSCACert,
- Usage: "Path to CA cert for db tls connection",
- Value: defaults.DBTlsCACert,
- EnvVars: []string{envNames.DbTLSCACert},
- },
- }
-}
diff --git a/cmd/gotosocial/flags.go b/cmd/gotosocial/debug.go
index 8e162f6c7..f66d5ac0c 100644
--- a/cmd/gotosocial/flags.go
+++ b/cmd/gotosocial/debug.go
@@ -19,31 +19,30 @@
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"
- "github.com/urfave/cli/v2"
)
-func getFlags() []cli.Flag {
- flagNames := config.GetFlagNames()
- envNames := config.GetEnvNames()
- defaults := config.GetDefaults()
-
- flags := []cli.Flag{}
- flagSets := [][]cli.Flag{
- generalFlags(flagNames, envNames, defaults),
- databaseFlags(flagNames, envNames, defaults),
- templateFlags(flagNames, envNames, defaults),
- accountsFlags(flagNames, envNames, defaults),
- mediaFlags(flagNames, envNames, defaults),
- storageFlags(flagNames, envNames, defaults),
- statusesFlags(flagNames, envNames, defaults),
- letsEncryptFlags(flagNames, envNames, defaults),
- oidcFlags(flagNames, envNames, defaults),
- smtpFlags(flagNames, envNames, defaults),
+func debugCommands() *cobra.Command {
+ debugCmd := &cobra.Command{
+ Use: "debug",
+ Short: "gotosocial debug-related tasks",
}
- for _, fs := range flagSets {
- flags = append(flags, fs...)
+
+ debugConfigCmd := &cobra.Command{
+ Use: "config",
+ Short: "print the collated config (derived from env, flag, and config file) to stdout",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), configaction.Config)
+ },
}
+ flag.Server(debugConfigCmd, config.Defaults)
- return flags
+ debugCmd.AddCommand(debugConfigCmd)
+ return debugCmd
}
diff --git a/cmd/gotosocial/flag/admin.go b/cmd/gotosocial/flag/admin.go
new file mode 100644
index 000000000..b087071bb
--- /dev/null
+++ b/cmd/gotosocial/flag/admin.go
@@ -0,0 +1,62 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package 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)
+ }
+}
diff --git a/cmd/gotosocial/flag/global.go b/cmd/gotosocial/flag/global.go
new file mode 100644
index 000000000..b7fb03e17
--- /dev/null
+++ b/cmd/gotosocial/flag/global.go
@@ -0,0 +1,45 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package 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().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)
+}
diff --git a/cmd/gotosocial/flag/server.go b/cmd/gotosocial/flag/server.go
new file mode 100644
index 000000000..3d3e946f3
--- /dev/null
+++ b/cmd/gotosocial/flag/server.go
@@ -0,0 +1,111 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package 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)
+}
+
+// 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)
+}
+
+// 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.StorageBasePath, values.StorageBasePath, usage.StorageBasePath)
+ cmd.Flags().String(config.Keys.StorageServeProtocol, values.StorageServeProtocol, usage.StorageServeProtocol)
+ cmd.Flags().String(config.Keys.StorageServeHost, values.StorageServeHost, usage.StorageServeHost)
+ cmd.Flags().String(config.Keys.StorageServeBasePath, values.StorageServeBasePath, usage.StorageServeBasePath)
+}
+
+// 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)
+}
diff --git a/cmd/gotosocial/flag/usage.go b/cmd/gotosocial/flag/usage.go
new file mode 100644
index 000000000..aa57048c1
--- /dev/null
+++ b/cmd/gotosocial/flag/usage.go
@@ -0,0 +1,80 @@
+/*
+ GoToSocial
+ Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+package flag
+
+import "github.com/superseriousbusiness/gotosocial/internal/config"
+
+var usage = config.KeyNames{
+ LogLevel: "Log level to run at: [trace, debug, info, warn, fatal]",
+ 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). 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 (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",
+ StorageBackend: "Storage backend to use for media attachments",
+ StorageBasePath: "Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir.",
+ StorageServeProtocol: "Protocol to use for serving media attachments (use https if storage is local)",
+ StorageServeHost: "Hostname to serve media attachments from (use the same value as host if storage is local)",
+ StorageServeBasePath: "Path to append to protocol and hostname to create the base path from which media files will be served (default will mostly be fine)",
+ 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'",
+ 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",
+}
diff --git a/cmd/gotosocial/generalflags.go b/cmd/gotosocial/generalflags.go
deleted file mode 100644
index b7e15ab20..000000000
--- a/cmd/gotosocial/generalflags.go
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func generalFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.StringFlag{
- Name: flagNames.LogLevel,
- Usage: "Log level to run at: debug, info, warn, fatal",
- Value: defaults.LogLevel,
- EnvVars: []string{envNames.LogLevel},
- },
- &cli.StringFlag{
- Name: flagNames.ApplicationName,
- Usage: "Name of the application, used in various places internally",
- Value: defaults.ApplicationName,
- EnvVars: []string{envNames.ApplicationName},
- Hidden: true,
- },
- &cli.StringFlag{
- Name: flagNames.ConfigPath,
- Usage: "Path to a yaml file containing gotosocial configuration. Values set in this file will be overwritten by values set as env vars or arguments",
- Value: defaults.ConfigPath,
- EnvVars: []string{envNames.ConfigPath},
- },
- &cli.StringFlag{
- Name: flagNames.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!",
- Value: defaults.Host,
- EnvVars: []string{envNames.Host},
- },
- &cli.StringFlag{
- Name: flagNames.AccountDomain,
- 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!",
- Value: defaults.AccountDomain,
- EnvVars: []string{envNames.AccountDomain},
- },
- &cli.StringFlag{
- Name: flagNames.Protocol,
- Usage: "Protocol to use for the REST api of the server (only use http for debugging and tests!)",
- Value: defaults.Protocol,
- EnvVars: []string{envNames.Protocol},
- },
- &cli.StringFlag{
- Name: flagNames.BindAddress,
- 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.",
- Value: defaults.BindAddress,
- EnvVars: []string{envNames.BindAddress},
- },
- &cli.IntFlag{
- Name: flagNames.Port,
- Usage: "Port to use for GoToSocial. Change this to 443 if you're running the binary directly on the host machine.",
- Value: defaults.Port,
- EnvVars: []string{envNames.Port},
- },
- &cli.StringSliceFlag{
- Name: flagNames.TrustedProxies,
- Usage: "Proxies to trust when parsing x-forwarded headers into real IPs.",
- Value: cli.NewStringSlice(defaults.TrustedProxies...),
- EnvVars: []string{envNames.TrustedProxies},
- },
- }
-}
diff --git a/cmd/gotosocial/letsencryptflags.go b/cmd/gotosocial/letsencryptflags.go
deleted file mode 100644
index 86079c015..000000000
--- a/cmd/gotosocial/letsencryptflags.go
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func letsEncryptFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.BoolFlag{
- Name: flagNames.LetsEncryptEnabled,
- Usage: "Enable letsencrypt TLS certs for this server. If set to true, then cert dir also needs to be set (or take the default).",
- Value: defaults.LetsEncryptEnabled,
- EnvVars: []string{envNames.LetsEncryptEnabled},
- },
- &cli.IntFlag{
- Name: flagNames.LetsEncryptPort,
- Usage: "Port to listen on for letsencrypt certificate challenges. Must not be the same as the GtS webserver/API port.",
- Value: defaults.LetsEncryptPort,
- EnvVars: []string{envNames.LetsEncryptPort},
- },
- &cli.StringFlag{
- Name: flagNames.LetsEncryptCertDir,
- Usage: "Directory to store acquired letsencrypt certificates.",
- Value: defaults.LetsEncryptCertDir,
- EnvVars: []string{envNames.LetsEncryptCertDir},
- },
- &cli.StringFlag{
- Name: flagNames.LetsEncryptEmailAddress,
- Usage: "Email address to use when requesting letsencrypt certs. Will receive updates on cert expiry etc.",
- Value: defaults.LetsEncryptEmailAddress,
- EnvVars: []string{envNames.LetsEncryptEmailAddress},
- },
- }
-}
diff --git a/cmd/gotosocial/main.go b/cmd/gotosocial/main.go
index 87c44487c..a0b8b1046 100644
--- a/cmd/gotosocial/main.go
+++ b/cmd/gotosocial/main.go
@@ -19,38 +19,59 @@
package main
import (
- "os"
-
"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/urfave/cli/v2"
+ "github.com/superseriousbusiness/gotosocial/internal/config"
)
-// Version is the software version of GtS being used
+// Version is the software version of GtS being used.
var Version string
-// Commit is the git commit of GtS being used
+// Commit is the git commit of GtS being used.
var Commit string
//go:generate swagger generate spec
func main() {
var v string
- if Commit == "" {
+ if len(Commit) < 7 {
v = Version
} else {
v = Version + " " + Commit[:7]
}
- flagsSlice := getFlags()
- app := &cli.App{
- Version: v,
- Usage: "a fediverse social media server",
- Flags: flagsSlice,
- Commands: getCommands(flagsSlice),
+ // override software version in viper store
+ viper.Set(config.Keys.SoftwareVersion, v)
+
+ // 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: v,
+ 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)
}
- if err := app.Run(os.Args); err != nil {
- logrus.Fatal(err)
+ // add subcommands
+ rootCmd.AddCommand(serverCommands())
+ rootCmd.AddCommand(testrigCommands())
+ rootCmd.AddCommand(debugCommands())
+ rootCmd.AddCommand(adminCommands())
+
+ // run
+ if err := rootCmd.Execute(); err != nil {
+ logrus.Fatalf("error executing command: %s", err)
}
}
diff --git a/cmd/gotosocial/mediaflags.go b/cmd/gotosocial/mediaflags.go
deleted file mode 100644
index abf009a89..000000000
--- a/cmd/gotosocial/mediaflags.go
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func mediaFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.IntFlag{
- Name: flagNames.MediaMaxImageSize,
- Usage: "Max size of accepted images in bytes",
- Value: defaults.MediaMaxImageSize,
- EnvVars: []string{envNames.MediaMaxImageSize},
- },
- &cli.IntFlag{
- Name: flagNames.MediaMaxVideoSize,
- Usage: "Max size of accepted videos in bytes",
- Value: defaults.MediaMaxVideoSize,
- EnvVars: []string{envNames.MediaMaxVideoSize},
- },
- &cli.IntFlag{
- Name: flagNames.MediaMinDescriptionChars,
- Usage: "Min required chars for an image description",
- Value: defaults.MediaMinDescriptionChars,
- EnvVars: []string{envNames.MediaMinDescriptionChars},
- },
- &cli.IntFlag{
- Name: flagNames.MediaMaxDescriptionChars,
- Usage: "Max permitted chars for an image description",
- Value: defaults.MediaMaxDescriptionChars,
- EnvVars: []string{envNames.MediaMaxDescriptionChars},
- },
- }
-}
diff --git a/cmd/gotosocial/oidcflags.go b/cmd/gotosocial/oidcflags.go
deleted file mode 100644
index 93b86b166..000000000
--- a/cmd/gotosocial/oidcflags.go
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func oidcFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.BoolFlag{
- Name: flagNames.OIDCEnabled,
- Usage: "Enabled OIDC authorization for this instance. If set to true, then the other OIDC flags must also be set.",
- Value: defaults.OIDCEnabled,
- EnvVars: []string{envNames.OIDCEnabled},
- },
- &cli.StringFlag{
- Name: flagNames.OIDCIdpName,
- Usage: "Name of the OIDC identity provider. Will be shown to the user when logging in.",
- Value: defaults.OIDCIdpName,
- EnvVars: []string{envNames.OIDCIdpName},
- },
- &cli.BoolFlag{
- Name: flagNames.OIDCSkipVerification,
- Usage: "Skip verification of tokens returned by the OIDC provider. Should only be set to 'true' for testing purposes, never in a production environment!",
- Value: defaults.OIDCSkipVerification,
- EnvVars: []string{envNames.OIDCSkipVerification},
- },
- &cli.StringFlag{
- Name: flagNames.OIDCIssuer,
- 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'",
- Value: defaults.OIDCIssuer,
- EnvVars: []string{envNames.OIDCIssuer},
- },
- &cli.StringFlag{
- Name: flagNames.OIDCClientID,
- Usage: "ClientID of GoToSocial, as registered with the OIDC provider.",
- Value: defaults.OIDCClientID,
- EnvVars: []string{envNames.OIDCClientID},
- },
- &cli.StringFlag{
- Name: flagNames.OIDCClientSecret,
- Usage: "ClientSecret of GoToSocial, as registered with the OIDC provider.",
- Value: defaults.OIDCClientSecret,
- EnvVars: []string{envNames.OIDCClientSecret},
- },
- &cli.StringSliceFlag{
- Name: flagNames.OIDCScopes,
- Usage: "ClientSecret of GoToSocial, as registered with the OIDC provider.",
- Value: cli.NewStringSlice(defaults.OIDCScopes...),
- EnvVars: []string{envNames.OIDCScopes},
- },
- }
-}
diff --git a/cmd/gotosocial/runaction.go b/cmd/gotosocial/runaction.go
deleted file mode 100644
index 96c4edaf6..000000000
--- a/cmd/gotosocial/runaction.go
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "fmt"
-
- "github.com/superseriousbusiness/gotosocial/internal/cliactions"
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/superseriousbusiness/gotosocial/internal/log"
- "github.com/urfave/cli/v2"
-)
-
-type MonkeyPatchedCLIContext struct {
- CLIContext *cli.Context
- AllFlags []cli.Flag
-}
-
-func (f MonkeyPatchedCLIContext) Bool(k string) bool { return f.CLIContext.Bool(k) }
-func (f MonkeyPatchedCLIContext) String(k string) string { return f.CLIContext.String(k) }
-func (f MonkeyPatchedCLIContext) StringSlice(k string) []string { return f.CLIContext.StringSlice(k) }
-func (f MonkeyPatchedCLIContext) Int(k string) int { return f.CLIContext.Int(k) }
-func (f MonkeyPatchedCLIContext) IsSet(k string) bool {
- for _, flag := range f.AllFlags {
- flagNames := flag.Names()
- for _, name := range flagNames {
- if name == k {
- return flag.IsSet()
- }
- }
-
- }
- return false
-}
-
-// runAction builds up the config and logger necessary for any
-// gotosocial action, and then executes the action.
-func runAction(c *cli.Context, allFlags []cli.Flag, a cliactions.GTSAction) error {
-
- // create a new *config.Config based on the config path provided...
- conf, err := config.FromFile(c.String(config.GetFlagNames().ConfigPath))
- if err != nil {
- return fmt.Errorf("error creating config: %s", err)
- }
-
- // ... and the flags set on the *cli.Context by urfave
- //
- // The IsSet function on the cli.Context object `c` here appears to have some issues right now, it always returns false in my tests.
- // However we can re-create the behaviour we want by simply referencing the flag objects we created previously
- // https://picopublish.sequentialread.com/files/chatlog_2021_11_18.txt
- monkeyPatchedCLIContext := MonkeyPatchedCLIContext{
- CLIContext: c,
- AllFlags: allFlags,
- }
- if err := conf.ParseCLIFlags(monkeyPatchedCLIContext, c.App.Version); err != nil {
- return fmt.Errorf("error parsing config: %s", err)
- }
-
- // initialize the global logger to the log level, with formatting and output splitter already set
- err = log.Initialize(conf.LogLevel)
- if err != nil {
- return fmt.Errorf("error creating logger: %s", err)
- }
-
- return a(c.Context, conf)
-}
diff --git a/cmd/gotosocial/templateflags.go b/cmd/gotosocial/server.go
index c7bf93bc0..742a4f505 100644
--- a/cmd/gotosocial/templateflags.go
+++ b/cmd/gotosocial/server.go
@@ -19,23 +19,31 @@
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"
- "github.com/urfave/cli/v2"
)
-func templateFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.StringFlag{
- Name: flagNames.TemplateBaseDir,
- Usage: "Basedir for html templating files for rendering pages and composing emails.",
- Value: defaults.TemplateBaseDir,
- EnvVars: []string{envNames.TemplateBaseDir},
+// serverCommands returns the 'server' subcommand
+func serverCommands() *cobra.Command {
+ serverCmd := &cobra.Command{
+ Use: "server",
+ Short: "gotosocial server-related tasks",
+ }
+
+ serverStartCmd := &cobra.Command{
+ Use: "start",
+ Short: "start the gotosocial server",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(cmd)
},
- &cli.StringFlag{
- Name: flagNames.AssetBaseDir,
- Usage: "Directory to serve static assets from, accessible at example.com/assets/",
- Value: defaults.AssetBaseDir,
- EnvVars: []string{envNames.AssetBaseDir},
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), server.Start)
},
}
+ flag.Server(serverStartCmd, config.Defaults)
+
+ serverCmd.AddCommand(serverStartCmd)
+ return serverCmd
}
diff --git a/cmd/gotosocial/smtpflags.go b/cmd/gotosocial/smtpflags.go
deleted file mode 100644
index 5c790ef7e..000000000
--- a/cmd/gotosocial/smtpflags.go
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func smtpFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.StringFlag{
- Name: flagNames.SMTPHost,
- Usage: "Host of the smtp server. Eg., 'smtp.eu.mailgun.org'",
- Value: defaults.SMTPHost,
- EnvVars: []string{envNames.SMTPHost},
- },
- &cli.IntFlag{
- Name: flagNames.SMTPPort,
- Usage: "Port of the smtp server. Eg., 587",
- Value: defaults.SMTPPort,
- EnvVars: []string{envNames.SMTPPort},
- },
- &cli.StringFlag{
- Name: flagNames.SMTPUsername,
- Usage: "Username to authenticate with the smtp server as. Eg., 'postmaster@mail.example.org'",
- Value: defaults.SMTPUsername,
- EnvVars: []string{envNames.SMTPUsername},
- },
- &cli.StringFlag{
- Name: flagNames.SMTPPassword,
- Usage: "Password to pass to the smtp server.",
- Value: defaults.SMTPPassword,
- EnvVars: []string{envNames.SMTPPassword},
- },
- &cli.StringFlag{
- Name: flagNames.SMTPFrom,
- Usage: "Address to use as the 'from' field of the email. Eg., 'gotosocial@example.org'",
- Value: defaults.SMTPFrom,
- EnvVars: []string{envNames.SMTPFrom},
- },
- }
-}
diff --git a/cmd/gotosocial/statusesflags.go b/cmd/gotosocial/statusesflags.go
deleted file mode 100644
index af52dc0ae..000000000
--- a/cmd/gotosocial/statusesflags.go
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func statusesFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.IntFlag{
- Name: flagNames.StatusesMaxChars,
- Usage: "Max permitted characters for posted statuses",
- Value: defaults.StatusesMaxChars,
- EnvVars: []string{envNames.StatusesMaxChars},
- },
- &cli.IntFlag{
- Name: flagNames.StatusesCWMaxChars,
- Usage: "Max permitted characters for content/spoiler warnings on statuses",
- Value: defaults.StatusesCWMaxChars,
- EnvVars: []string{envNames.StatusesCWMaxChars},
- },
- &cli.IntFlag{
- Name: flagNames.StatusesPollMaxOptions,
- Usage: "Max amount of options permitted on a poll",
- Value: defaults.StatusesPollMaxOptions,
- EnvVars: []string{envNames.StatusesPollMaxOptions},
- },
- &cli.IntFlag{
- Name: flagNames.StatusesPollOptionMaxChars,
- Usage: "Max amount of characters for a poll option",
- Value: defaults.StatusesPollOptionMaxChars,
- EnvVars: []string{envNames.StatusesPollOptionMaxChars},
- },
- &cli.IntFlag{
- Name: flagNames.StatusesMaxMediaFiles,
- Usage: "Maximum number of media files/attachments per status",
- Value: defaults.StatusesMaxMediaFiles,
- EnvVars: []string{envNames.StatusesMaxMediaFiles},
- },
- }
-}
diff --git a/cmd/gotosocial/storageflags.go b/cmd/gotosocial/storageflags.go
deleted file mode 100644
index 326e1fae5..000000000
--- a/cmd/gotosocial/storageflags.go
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- GoToSocial
- Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package main
-
-import (
- "github.com/superseriousbusiness/gotosocial/internal/config"
- "github.com/urfave/cli/v2"
-)
-
-func storageFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag {
- return []cli.Flag{
- &cli.StringFlag{
- Name: flagNames.StorageBackend,
- Usage: "Storage backend to use for media attachments",
- Value: defaults.StorageBackend,
- EnvVars: []string{envNames.StorageBackend},
- },
- &cli.StringFlag{
- Name: flagNames.StorageBasePath,
- Usage: "Full path to an already-created directory where gts should store/retrieve media files. Subfolders will be created within this dir.",
- Value: defaults.StorageBasePath,
- EnvVars: []string{envNames.StorageBasePath},
- },
- &cli.StringFlag{
- Name: flagNames.StorageServeProtocol,
- Usage: "Protocol to use for serving media attachments (use https if storage is local)",
- Value: defaults.StorageServeProtocol,
- EnvVars: []string{envNames.StorageServeProtocol},
- },
- &cli.StringFlag{
- Name: flagNames.StorageServeHost,
- Usage: "Hostname to serve media attachments from (use the same value as host if storage is local)",
- Value: defaults.StorageServeHost,
- EnvVars: []string{envNames.StorageServeHost},
- },
- &cli.StringFlag{
- Name: flagNames.StorageServeBasePath,
- Usage: "Path to append to protocol and hostname to create the base path from which media files will be served (default will mostly be fine)",
- Value: defaults.StorageServeBasePath,
- EnvVars: []string{envNames.StorageServeBasePath},
- },
- }
-}
diff --git a/cmd/gotosocial/servercommands.go b/cmd/gotosocial/testrig.go
index fb6574216..b78996475 100644
--- a/cmd/gotosocial/servercommands.go
+++ b/cmd/gotosocial/testrig.go
@@ -19,24 +19,24 @@
package main
import (
- "github.com/superseriousbusiness/gotosocial/internal/cliactions/server"
- "github.com/urfave/cli/v2"
+ "github.com/spf13/cobra"
+ "github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action/testrig"
)
-func serverCommands(allFlags []cli.Flag) []*cli.Command {
- return []*cli.Command{
- {
- Name: "server",
- Usage: "gotosocial server-related tasks",
- Subcommands: []*cli.Command{
- {
- Name: "start",
- Usage: "start the gotosocial server",
- Action: func(c *cli.Context) error {
- return runAction(c, allFlags, server.Start)
- },
- },
- },
+func testrigCommands() *cobra.Command {
+ testrigCmd := &cobra.Command{
+ Use: "testrig",
+ Short: "gotosocial testrig-related tasks",
+ }
+
+ testrigStartCmd := &cobra.Command{
+ Use: "start",
+ Short: "start the gotosocial testrig server",
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), testrig.Start)
},
}
+
+ testrigCmd.AddCommand(testrigStartCmd)
+ return testrigCmd
}