summaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorLibravatar tobi <31960611+tsmethurst@users.noreply.github.com>2023-07-23 12:33:17 +0200
committerLibravatar GitHub <noreply@github.com>2023-07-23 12:33:17 +0200
commit5a29a031adbcaca85ad641bf74254d3ea985d03c (patch)
treeeda06b4d3b09207bc6d4dc6e9e659e8f283028dc /cmd
parent[feature] Report Masto version in /api/v1/instance (#1977) (diff)
downloadgotosocial-5a29a031adbcaca85ad641bf74254d3ea985d03c.tar.xz
[chore] Admin CLI + new account creation refactoring (#2008)
* set maxPasswordLength to 72 bytes, rename validate function * refactor NewSignup * refactor admin account CLI commands * refactor oidc create user * refactor processor create * tweak password change, check old != new password
Diffstat (limited to 'cmd')
-rw-r--r--cmd/gotosocial/action/admin/account/account.go236
1 files changed, 106 insertions, 130 deletions
diff --git a/cmd/gotosocial/action/admin/account/account.go b/cmd/gotosocial/action/admin/account/account.go
index 3941769ec..9bb5b27c1 100644
--- a/cmd/gotosocial/action/admin/account/account.go
+++ b/cmd/gotosocial/action/admin/account/account.go
@@ -19,7 +19,6 @@ package account
import (
"context"
- "errors"
"fmt"
"os"
"text/tabwriter"
@@ -28,88 +27,101 @@ import (
"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/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/state"
"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 {
+func initState(ctx context.Context) (*state.State, error) {
var state state.State
state.Caches.Init()
+ state.Caches.Start()
state.Workers.Start()
+ // Set the state DB connection
dbConn, err := bundb.NewBunDBService(ctx, &state)
if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
+ return nil, fmt.Errorf("error creating dbConn: %w", err)
}
-
- // Set the state DB connection
state.DB = dbConn
- username := config.GetAdminAccountUsername()
- if username == "" {
- return errors.New("no username set")
+ return &state, nil
+}
+
+func stopState(ctx context.Context, state *state.State) error {
+ if err := state.DB.Stop(ctx); err != nil {
+ return fmt.Errorf("error stopping dbConn: %w", err)
+ }
+
+ state.Workers.Stop()
+ state.Caches.Stop()
+
+ return nil
+}
+
+// Create creates a new account and user
+// in the database using the provided flags.
+var Create action.GTSAction = func(ctx context.Context) error {
+ state, err := initState(ctx)
+ if err != nil {
+ return err
}
+
+ username := config.GetAdminAccountUsername()
if err := validate.Username(username); err != nil {
return err
}
- usernameAvailable, err := dbConn.IsUsernameAvailable(ctx, username)
+ usernameAvailable, err := state.DB.IsUsernameAvailable(ctx, username)
if err != nil {
return err
}
+
if !usernameAvailable {
return fmt.Errorf("username %s is already in use", username)
}
email := config.GetAdminAccountEmail()
- if email == "" {
- return errors.New("no email set")
- }
if err := validate.Email(email); err != nil {
return err
}
- emailAvailable, err := dbConn.IsEmailAvailable(ctx, email)
+ emailAvailable, err := state.DB.IsEmailAvailable(ctx, email)
if err != nil {
return err
}
+
if !emailAvailable {
return fmt.Errorf("email address %s is already in use", email)
}
password := config.GetAdminAccountPassword()
- if password == "" {
- return errors.New("no password set")
- }
- if err := validate.NewPassword(password); err != nil {
+ if err := validate.Password(password); err != nil {
return err
}
- _, err = dbConn.NewSignup(ctx, username, "", false, email, password, nil, "", "", true, "", false)
- if err != nil {
+ if _, err := state.DB.NewSignup(ctx, gtsmodel.NewSignup{
+ Username: username,
+ Email: email,
+ Password: password,
+ EmailVerified: true, // Assume cli user wants email marked as verified already.
+ PreApproved: true, // Assume cli user wants account marked as approved already.
+ }); err != nil {
return err
}
- return dbConn.Stop(ctx)
+ return stopState(ctx, state)
}
// 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)
+ state, err := initState(ctx)
if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
+ return err
}
- // Set the state DB connection
- state.DB = dbConn
-
- users, err := dbConn.GetAllUsers(ctx)
+ users, err := state.DB.GetAllUsers(ctx)
if err != nil {
return err
}
@@ -140,218 +152,182 @@ var List action.GTSAction = func(ctx context.Context) error {
return nil
}
-// Confirm sets a user to Approved, sets Email to the current UnconfirmedEmail value, and sets ConfirmedAt to now.
+// 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
- state.Caches.Init()
- state.Workers.Start()
-
- dbConn, err := bundb.NewBunDBService(ctx, &state)
+ state, err := initState(ctx)
if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
+ return err
}
- // Set the state DB connection
- state.DB = dbConn
-
username := config.GetAdminAccountUsername()
- if username == "" {
- return errors.New("no username set")
- }
if err := validate.Username(username); err != nil {
return err
}
- a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
+ account, err := state.DB.GetAccountByUsernameDomain(ctx, username, "")
if err != nil {
return err
}
- u, err := dbConn.GetUserByAccountID(ctx, a.ID)
+ user, err := state.DB.GetUserByAccountID(ctx, account.ID)
if err != nil {
return err
}
- updatingColumns := []string{"approved", "email", "confirmed_at"}
- approved := true
- u.Approved = &approved
- u.Email = u.UnconfirmedEmail
- u.ConfirmedAt = time.Now()
- if err := dbConn.UpdateUser(ctx, u, updatingColumns...); err != nil {
+ user.Approved = func() *bool { a := true; return &a }()
+ user.Email = user.UnconfirmedEmail
+ user.ConfirmedAt = time.Now()
+ if err := state.DB.UpdateUser(
+ ctx, user,
+ "approved", "email", "confirmed_at",
+ ); err != nil {
return err
}
- return dbConn.Stop(ctx)
+ return stopState(ctx, state)
}
-// Promote sets a user to admin.
+// Promote sets admin + moderator flags on a user to true.
var Promote action.GTSAction = func(ctx context.Context) error {
- var state state.State
- state.Caches.Init()
- state.Workers.Start()
-
- dbConn, err := bundb.NewBunDBService(ctx, &state)
+ state, err := initState(ctx)
if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
+ return err
}
- // Set the state DB connection
- state.DB = dbConn
-
username := config.GetAdminAccountUsername()
- if username == "" {
- return errors.New("no username set")
- }
if err := validate.Username(username); err != nil {
return err
}
- a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
+ account, err := state.DB.GetAccountByUsernameDomain(ctx, username, "")
if err != nil {
return err
}
- u, err := dbConn.GetUserByAccountID(ctx, a.ID)
+ user, err := state.DB.GetUserByAccountID(ctx, account.ID)
if err != nil {
return err
}
- admin := true
- u.Admin = &admin
- if err := dbConn.UpdateUser(ctx, u, "admin"); err != nil {
+ user.Admin = func() *bool { a := true; return &a }()
+ user.Moderator = func() *bool { a := true; return &a }()
+ if err := state.DB.UpdateUser(
+ ctx, user,
+ "admin", "moderator",
+ ); err != nil {
return err
}
- return dbConn.Stop(ctx)
+ return stopState(ctx, state)
}
-// Demote sets admin on a user to false.
+// Demote sets admin + moderator flags on a user to false.
var Demote action.GTSAction = func(ctx context.Context) error {
- var state state.State
- state.Caches.Init()
- state.Workers.Start()
-
- dbConn, err := bundb.NewBunDBService(ctx, &state)
+ state, err := initState(ctx)
if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
+ return err
}
- // Set the state DB connection
- state.DB = dbConn
-
username := config.GetAdminAccountUsername()
- if username == "" {
- return errors.New("no username set")
- }
if err := validate.Username(username); err != nil {
return err
}
- a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
+ a, err := state.DB.GetAccountByUsernameDomain(ctx, username, "")
if err != nil {
return err
}
- u, err := dbConn.GetUserByAccountID(ctx, a.ID)
+ user, err := state.DB.GetUserByAccountID(ctx, a.ID)
if err != nil {
return err
}
- admin := false
- u.Admin = &admin
- if err := dbConn.UpdateUser(ctx, u, "admin"); err != nil {
+ user.Admin = func() *bool { a := false; return &a }()
+ user.Moderator = func() *bool { a := false; return &a }()
+ if err := state.DB.UpdateUser(
+ ctx, user,
+ "admin", "moderator",
+ ); err != nil {
return err
}
- return dbConn.Stop(ctx)
+ return stopState(ctx, state)
}
// Disable sets Disabled to true on a user.
var Disable action.GTSAction = func(ctx context.Context) error {
- var state state.State
- state.Caches.Init()
- state.Workers.Start()
-
- dbConn, err := bundb.NewBunDBService(ctx, &state)
+ state, err := initState(ctx)
if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
+ return err
}
- // Set the state DB connection
- state.DB = dbConn
-
username := config.GetAdminAccountUsername()
- if username == "" {
- return errors.New("no username set")
- }
if err := validate.Username(username); err != nil {
return err
}
- a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
+ account, err := state.DB.GetAccountByUsernameDomain(ctx, username, "")
if err != nil {
return err
}
- u, err := dbConn.GetUserByAccountID(ctx, a.ID)
+ user, err := state.DB.GetUserByAccountID(ctx, account.ID)
if err != nil {
return err
}
- disabled := true
- u.Disabled = &disabled
- if err := dbConn.UpdateUser(ctx, u, "disabled"); err != nil {
+ user.Disabled = func() *bool { d := true; return &d }()
+ if err := state.DB.UpdateUser(
+ ctx, user,
+ "disabled",
+ ); err != nil {
return err
}
- return dbConn.Stop(ctx)
+ return stopState(ctx, state)
}
// Password sets the password of target account.
var Password action.GTSAction = func(ctx context.Context) error {
- var state state.State
- state.Caches.Init()
- state.Workers.Start()
-
- dbConn, err := bundb.NewBunDBService(ctx, &state)
+ state, err := initState(ctx)
if err != nil {
- return fmt.Errorf("error creating dbservice: %s", err)
+ return err
}
- // Set the state DB connection
- state.DB = dbConn
-
username := config.GetAdminAccountUsername()
- if username == "" {
- return errors.New("no username set")
- }
if err := validate.Username(username); err != nil {
return err
}
password := config.GetAdminAccountPassword()
- if password == "" {
- return errors.New("no password set")
- }
- if err := validate.NewPassword(password); err != nil {
+ if err := validate.Password(password); err != nil {
return err
}
- a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
+ account, err := state.DB.GetAccountByUsernameDomain(ctx, username, "")
if err != nil {
return err
}
- u, err := dbConn.GetUserByAccountID(ctx, a.ID)
+ user, err := state.DB.GetUserByAccountID(ctx, account.ID)
if err != nil {
return err
}
- pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
+ encryptedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return fmt.Errorf("error hashing password: %s", err)
}
- u.EncryptedPassword = string(pw)
- return dbConn.UpdateUser(ctx, u, "encrypted_password")
+ user.EncryptedPassword = string(encryptedPassword)
+ if err := state.DB.UpdateUser(
+ ctx, user,
+ "encrypted_password",
+ ); err != nil {
+ return err
+ }
+
+ return stopState(ctx, state)
}