gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

account.go (8510B)


      1 // GoToSocial
      2 // Copyright (C) GoToSocial Authors admin@gotosocial.org
      3 // SPDX-License-Identifier: AGPL-3.0-or-later
      4 //
      5 // This program is free software: you can redistribute it and/or modify
      6 // it under the terms of the GNU Affero General Public License as published by
      7 // the Free Software Foundation, either version 3 of the License, or
      8 // (at your option) any later version.
      9 //
     10 // This program is distributed in the hope that it will be useful,
     11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 // GNU Affero General Public License for more details.
     14 //
     15 // You should have received a copy of the GNU Affero General Public License
     16 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
     17 
     18 package account
     19 
     20 import (
     21 	"context"
     22 	"errors"
     23 	"fmt"
     24 	"os"
     25 	"text/tabwriter"
     26 	"time"
     27 
     28 	"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
     29 	"github.com/superseriousbusiness/gotosocial/internal/config"
     30 	"github.com/superseriousbusiness/gotosocial/internal/db/bundb"
     31 	"github.com/superseriousbusiness/gotosocial/internal/state"
     32 	"github.com/superseriousbusiness/gotosocial/internal/validate"
     33 	"golang.org/x/crypto/bcrypt"
     34 )
     35 
     36 // Create creates a new account in the database using the provided flags.
     37 var Create action.GTSAction = func(ctx context.Context) error {
     38 	var state state.State
     39 	state.Caches.Init()
     40 	state.Workers.Start()
     41 
     42 	dbConn, err := bundb.NewBunDBService(ctx, &state)
     43 	if err != nil {
     44 		return fmt.Errorf("error creating dbservice: %s", err)
     45 	}
     46 
     47 	// Set the state DB connection
     48 	state.DB = dbConn
     49 
     50 	username := config.GetAdminAccountUsername()
     51 	if username == "" {
     52 		return errors.New("no username set")
     53 	}
     54 	if err := validate.Username(username); err != nil {
     55 		return err
     56 	}
     57 
     58 	usernameAvailable, err := dbConn.IsUsernameAvailable(ctx, username)
     59 	if err != nil {
     60 		return err
     61 	}
     62 	if !usernameAvailable {
     63 		return fmt.Errorf("username %s is already in use", username)
     64 	}
     65 
     66 	email := config.GetAdminAccountEmail()
     67 	if email == "" {
     68 		return errors.New("no email set")
     69 	}
     70 	if err := validate.Email(email); err != nil {
     71 		return err
     72 	}
     73 
     74 	emailAvailable, err := dbConn.IsEmailAvailable(ctx, email)
     75 	if err != nil {
     76 		return err
     77 	}
     78 	if !emailAvailable {
     79 		return fmt.Errorf("email address %s is already in use", email)
     80 	}
     81 
     82 	password := config.GetAdminAccountPassword()
     83 	if password == "" {
     84 		return errors.New("no password set")
     85 	}
     86 	if err := validate.NewPassword(password); err != nil {
     87 		return err
     88 	}
     89 
     90 	_, err = dbConn.NewSignup(ctx, username, "", false, email, password, nil, "", "", true, "", false)
     91 	if err != nil {
     92 		return err
     93 	}
     94 
     95 	return dbConn.Stop(ctx)
     96 }
     97 
     98 // List returns all existing local accounts.
     99 var List action.GTSAction = func(ctx context.Context) error {
    100 	var state state.State
    101 	state.Caches.Init()
    102 	state.Workers.Start()
    103 
    104 	dbConn, err := bundb.NewBunDBService(ctx, &state)
    105 	if err != nil {
    106 		return fmt.Errorf("error creating dbservice: %s", err)
    107 	}
    108 
    109 	// Set the state DB connection
    110 	state.DB = dbConn
    111 
    112 	users, err := dbConn.GetAllUsers(ctx)
    113 	if err != nil {
    114 		return err
    115 	}
    116 
    117 	fmtBool := func(b *bool) string {
    118 		if b == nil {
    119 			return "unknown"
    120 		}
    121 		if *b {
    122 			return "yes"
    123 		}
    124 		return "no"
    125 	}
    126 
    127 	fmtDate := func(t time.Time) string {
    128 		if t.Equal(time.Time{}) {
    129 			return "no"
    130 		}
    131 		return "yes"
    132 	}
    133 
    134 	w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', 0)
    135 	fmt.Fprintln(w, "user\taccount\tapproved\tadmin\tmoderator\tsuspended\tconfirmed")
    136 	for _, u := range users {
    137 		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))
    138 	}
    139 	w.Flush()
    140 	return nil
    141 }
    142 
    143 // Confirm sets a user to Approved, sets Email to the current UnconfirmedEmail value, and sets ConfirmedAt to now.
    144 var Confirm action.GTSAction = func(ctx context.Context) error {
    145 	var state state.State
    146 	state.Caches.Init()
    147 	state.Workers.Start()
    148 
    149 	dbConn, err := bundb.NewBunDBService(ctx, &state)
    150 	if err != nil {
    151 		return fmt.Errorf("error creating dbservice: %s", err)
    152 	}
    153 
    154 	// Set the state DB connection
    155 	state.DB = dbConn
    156 
    157 	username := config.GetAdminAccountUsername()
    158 	if username == "" {
    159 		return errors.New("no username set")
    160 	}
    161 	if err := validate.Username(username); err != nil {
    162 		return err
    163 	}
    164 
    165 	a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
    166 	if err != nil {
    167 		return err
    168 	}
    169 
    170 	u, err := dbConn.GetUserByAccountID(ctx, a.ID)
    171 	if err != nil {
    172 		return err
    173 	}
    174 
    175 	updatingColumns := []string{"approved", "email", "confirmed_at"}
    176 	approved := true
    177 	u.Approved = &approved
    178 	u.Email = u.UnconfirmedEmail
    179 	u.ConfirmedAt = time.Now()
    180 	if err := dbConn.UpdateUser(ctx, u, updatingColumns...); err != nil {
    181 		return err
    182 	}
    183 
    184 	return dbConn.Stop(ctx)
    185 }
    186 
    187 // Promote sets a user to admin.
    188 var Promote action.GTSAction = func(ctx context.Context) error {
    189 	var state state.State
    190 	state.Caches.Init()
    191 	state.Workers.Start()
    192 
    193 	dbConn, err := bundb.NewBunDBService(ctx, &state)
    194 	if err != nil {
    195 		return fmt.Errorf("error creating dbservice: %s", err)
    196 	}
    197 
    198 	// Set the state DB connection
    199 	state.DB = dbConn
    200 
    201 	username := config.GetAdminAccountUsername()
    202 	if username == "" {
    203 		return errors.New("no username set")
    204 	}
    205 	if err := validate.Username(username); err != nil {
    206 		return err
    207 	}
    208 
    209 	a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
    210 	if err != nil {
    211 		return err
    212 	}
    213 
    214 	u, err := dbConn.GetUserByAccountID(ctx, a.ID)
    215 	if err != nil {
    216 		return err
    217 	}
    218 
    219 	admin := true
    220 	u.Admin = &admin
    221 	if err := dbConn.UpdateUser(ctx, u, "admin"); err != nil {
    222 		return err
    223 	}
    224 
    225 	return dbConn.Stop(ctx)
    226 }
    227 
    228 // Demote sets admin on a user to false.
    229 var Demote action.GTSAction = func(ctx context.Context) error {
    230 	var state state.State
    231 	state.Caches.Init()
    232 	state.Workers.Start()
    233 
    234 	dbConn, err := bundb.NewBunDBService(ctx, &state)
    235 	if err != nil {
    236 		return fmt.Errorf("error creating dbservice: %s", err)
    237 	}
    238 
    239 	// Set the state DB connection
    240 	state.DB = dbConn
    241 
    242 	username := config.GetAdminAccountUsername()
    243 	if username == "" {
    244 		return errors.New("no username set")
    245 	}
    246 	if err := validate.Username(username); err != nil {
    247 		return err
    248 	}
    249 
    250 	a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
    251 	if err != nil {
    252 		return err
    253 	}
    254 
    255 	u, err := dbConn.GetUserByAccountID(ctx, a.ID)
    256 	if err != nil {
    257 		return err
    258 	}
    259 
    260 	admin := false
    261 	u.Admin = &admin
    262 	if err := dbConn.UpdateUser(ctx, u, "admin"); err != nil {
    263 		return err
    264 	}
    265 
    266 	return dbConn.Stop(ctx)
    267 }
    268 
    269 // Disable sets Disabled to true on a user.
    270 var Disable action.GTSAction = func(ctx context.Context) error {
    271 	var state state.State
    272 	state.Caches.Init()
    273 	state.Workers.Start()
    274 
    275 	dbConn, err := bundb.NewBunDBService(ctx, &state)
    276 	if err != nil {
    277 		return fmt.Errorf("error creating dbservice: %s", err)
    278 	}
    279 
    280 	// Set the state DB connection
    281 	state.DB = dbConn
    282 
    283 	username := config.GetAdminAccountUsername()
    284 	if username == "" {
    285 		return errors.New("no username set")
    286 	}
    287 	if err := validate.Username(username); err != nil {
    288 		return err
    289 	}
    290 
    291 	a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
    292 	if err != nil {
    293 		return err
    294 	}
    295 
    296 	u, err := dbConn.GetUserByAccountID(ctx, a.ID)
    297 	if err != nil {
    298 		return err
    299 	}
    300 
    301 	disabled := true
    302 	u.Disabled = &disabled
    303 	if err := dbConn.UpdateUser(ctx, u, "disabled"); err != nil {
    304 		return err
    305 	}
    306 
    307 	return dbConn.Stop(ctx)
    308 }
    309 
    310 // Password sets the password of target account.
    311 var Password action.GTSAction = func(ctx context.Context) error {
    312 	var state state.State
    313 	state.Caches.Init()
    314 	state.Workers.Start()
    315 
    316 	dbConn, err := bundb.NewBunDBService(ctx, &state)
    317 	if err != nil {
    318 		return fmt.Errorf("error creating dbservice: %s", err)
    319 	}
    320 
    321 	// Set the state DB connection
    322 	state.DB = dbConn
    323 
    324 	username := config.GetAdminAccountUsername()
    325 	if username == "" {
    326 		return errors.New("no username set")
    327 	}
    328 	if err := validate.Username(username); err != nil {
    329 		return err
    330 	}
    331 
    332 	password := config.GetAdminAccountPassword()
    333 	if password == "" {
    334 		return errors.New("no password set")
    335 	}
    336 	if err := validate.NewPassword(password); err != nil {
    337 		return err
    338 	}
    339 
    340 	a, err := dbConn.GetAccountByUsernameDomain(ctx, username, "")
    341 	if err != nil {
    342 		return err
    343 	}
    344 
    345 	u, err := dbConn.GetUserByAccountID(ctx, a.ID)
    346 	if err != nil {
    347 		return err
    348 	}
    349 
    350 	pw, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
    351 	if err != nil {
    352 		return fmt.Errorf("error hashing password: %s", err)
    353 	}
    354 
    355 	u.EncryptedPassword = string(pw)
    356 	return dbConn.UpdateUser(ctx, u, "encrypted_password")
    357 }