commit 7d098633937a219aa96f1574fa9cc15aec1dd9fe
parent 9e1756ce8b0986132ff077813be23bb45a7c9db7
Author: Daenney <daenney@users.noreply.github.com>
Date: Mon, 27 Mar 2023 16:02:26 +0200
[feature] Add list command to admin account (#1648)
* [feature] Add list command to admin account
Relates to: #388
* Print booleans as yes/no too
Diffstat:
5 files changed, 81 insertions(+), 0 deletions(-)
diff --git a/cmd/gotosocial/action/admin/account/account.go b/cmd/gotosocial/action/admin/account/account.go
@@ -21,6 +21,8 @@ import (
"context"
"errors"
"fmt"
+ "os"
+ "text/tabwriter"
"time"
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
@@ -93,6 +95,51 @@ var Create action.GTSAction = func(ctx context.Context) error {
return dbConn.Stop(ctx)
}
+// List returns all existing local accounts.
+var List action.GTSAction = func(ctx context.Context) error {
+ var state state.State
+ state.Caches.Init()
+ state.Workers.Start()
+
+ dbConn, err := bundb.NewBunDBService(ctx, &state)
+ if err != nil {
+ return fmt.Errorf("error creating dbservice: %s", err)
+ }
+
+ // Set the state DB connection
+ state.DB = dbConn
+
+ users, err := dbConn.GetAllUsers(ctx)
+ if err != nil {
+ return err
+ }
+
+ fmtBool := func(b *bool) string {
+ if b == nil {
+ return "unknown"
+ }
+ if *b {
+ return "yes"
+ }
+ return "no"
+ }
+
+ fmtDate := func(t time.Time) string {
+ if t.Equal(time.Time{}) {
+ return "no"
+ }
+ return "yes"
+ }
+
+ w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
+ fmt.Fprintln(w, "user\taccount\tapproved\tadmin\tmoderator\tsuspended\tconfirmed")
+ for _, u := range users {
+ fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\t%s\n", u.Account.Username, u.AccountID, fmtBool(u.Approved), fmtBool(u.Admin), fmtBool(u.Moderator), fmtDate(u.Account.SuspendedAt), fmtDate(u.ConfirmedAt))
+ }
+ w.Flush()
+ return nil
+}
+
// 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 {
var state state.State
diff --git a/cmd/gotosocial/admin.go b/cmd/gotosocial/admin.go
@@ -54,6 +54,18 @@ func adminCommands() *cobra.Command {
config.AddAdminAccountCreate(adminAccountCreateCmd)
adminAccountCmd.AddCommand(adminAccountCreateCmd)
+ adminAccountListCmd := &cobra.Command{
+ Use: "list",
+ Short: "list all existing local accounts",
+ PreRunE: func(cmd *cobra.Command, args []string) error {
+ return preRun(preRunArgs{cmd: cmd})
+ },
+ RunE: func(cmd *cobra.Command, args []string) error {
+ return run(cmd.Context(), account.List)
+ },
+ }
+ adminAccountCmd.AddCommand(adminAccountListCmd)
+
adminAccountConfirmCmd := &cobra.Command{
Use: "confirm",
Short: "confirm an existing local account manually, thereby skipping email confirmation",
diff --git a/internal/db/bundb/user.go b/internal/db/bundb/user.go
@@ -122,6 +122,20 @@ func (u *userDB) GetUserByConfirmationToken(ctx context.Context, confirmationTok
}, confirmationToken)
}
+func (u *userDB) GetAllUsers(ctx context.Context) ([]*gtsmodel.User, db.Error) {
+ var users []*gtsmodel.User
+ q := u.conn.
+ NewSelect().
+ Model(&users).
+ Relation("Account")
+
+ if err := q.Scan(ctx); err != nil {
+ return nil, u.conn.ProcessError(err)
+ }
+
+ return users, nil
+}
+
func (u *userDB) PutUser(ctx context.Context, user *gtsmodel.User) db.Error {
return u.state.Caches.GTS.User().Store(user, func() error {
_, err := u.conn.
diff --git a/internal/db/bundb/user_test.go b/internal/db/bundb/user_test.go
@@ -29,6 +29,12 @@ type UserTestSuite struct {
BunDBStandardTestSuite
}
+func (suite *UserTestSuite) TestGetAllUsers() {
+ users, err := suite.db.GetAllUsers(context.Background())
+ suite.NoError(err)
+ suite.Len(users, len(suite.testUsers))
+}
+
func (suite *UserTestSuite) TestGetUser() {
user, err := suite.db.GetUserByID(context.Background(), suite.testUsers["local_account_1"].ID)
suite.NoError(err)
diff --git a/internal/db/user.go b/internal/db/user.go
@@ -25,6 +25,8 @@ import (
// User contains functions related to user getting/setting/creation.
type User interface {
+ // GetAllUsers returns all local user accounts, or an error if something goes wrong.
+ GetAllUsers(ctx context.Context) ([]*gtsmodel.User, Error)
// GetUserByID returns one user with the given ID, or an error if something goes wrong.
GetUserByID(ctx context.Context, id string) (*gtsmodel.User, Error)
// GetUserByAccountID returns one user by its account ID, or an error if something goes wrong.