chore(tfstated): refactor setting last login date time on successful HTTP basic auth
This commit is contained in:
parent
6d00e12097
commit
1dbb1b9ee7
2 changed files with 39 additions and 32 deletions
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.adyxax.org/adyxax/tfstated/pkg/database"
|
||||
"git.adyxax.org/adyxax/tfstated/pkg/helpers"
|
||||
|
@ -29,9 +28,7 @@ func Middleware(db *database.DB) func(http.Handler) http.Handler {
|
|||
helpers.ErrorResponse(w, http.StatusForbidden, fmt.Errorf("Forbidden"))
|
||||
return
|
||||
}
|
||||
now := time.Now().UTC()
|
||||
_, err = db.Exec(`UPDATE accounts SET last_login = ? WHERE id = ?`, now.Unix(), account.Id)
|
||||
if err != nil {
|
||||
if err := db.TouchAccount(account); err != nil {
|
||||
helpers.ErrorResponse(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -17,6 +17,36 @@ var AdvertiseAdminPassword = func(password string) {
|
|||
slog.Info("Generated an initial admin password, please change it or delete the admin account after your first login", "password", password)
|
||||
}
|
||||
|
||||
func (db *DB) InitAdminAccount() error {
|
||||
return db.WithTransaction(func(tx *sql.Tx) error {
|
||||
var hasAdminAccount bool
|
||||
if err := tx.QueryRowContext(db.ctx, `SELECT EXISTS (SELECT 1 FROM accounts WHERE is_admin);`).Scan(&hasAdminAccount); err != nil {
|
||||
return fmt.Errorf("failed to select if there is an admin account in the database: %w", err)
|
||||
}
|
||||
if !hasAdminAccount {
|
||||
var password uuid.UUID
|
||||
if err := password.Generate(uuid.V4); err != nil {
|
||||
return fmt.Errorf("failed to generate initial admin password: %w", err)
|
||||
}
|
||||
salt := helpers.GenerateSalt()
|
||||
hash := helpers.HashPassword(password.String(), salt)
|
||||
if _, err := tx.ExecContext(db.ctx,
|
||||
`INSERT INTO accounts(username, salt, password_hash, is_admin)
|
||||
VALUES ("admin", :salt, :hash, TRUE)
|
||||
ON CONFLICT DO UPDATE SET password_hash = :hash
|
||||
WHERE username = "admin";`,
|
||||
sql.Named("salt", salt),
|
||||
sql.Named("hash", hash),
|
||||
); err == nil {
|
||||
AdvertiseAdminPassword(password.String())
|
||||
} else {
|
||||
return fmt.Errorf("failed to set initial admin password: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (db *DB) LoadAccountByUsername(username string) (*model.Account, error) {
|
||||
account := model.Account{
|
||||
Username: username,
|
||||
|
@ -49,32 +79,12 @@ func (db *DB) LoadAccountByUsername(username string) (*model.Account, error) {
|
|||
return &account, nil
|
||||
}
|
||||
|
||||
func (db *DB) InitAdminAccount() error {
|
||||
return db.WithTransaction(func(tx *sql.Tx) error {
|
||||
var hasAdminAccount bool
|
||||
if err := tx.QueryRowContext(db.ctx, `SELECT EXISTS (SELECT 1 FROM accounts WHERE is_admin);`).Scan(&hasAdminAccount); err != nil {
|
||||
return fmt.Errorf("failed to select if there is an admin account in the database: %w", err)
|
||||
}
|
||||
if !hasAdminAccount {
|
||||
var password uuid.UUID
|
||||
if err := password.Generate(uuid.V4); err != nil {
|
||||
return fmt.Errorf("failed to generate initial admin password: %w", err)
|
||||
}
|
||||
salt := helpers.GenerateSalt()
|
||||
hash := helpers.HashPassword(password.String(), salt)
|
||||
if _, err := tx.ExecContext(db.ctx,
|
||||
`INSERT INTO accounts(username, salt, password_hash, is_admin)
|
||||
VALUES ("admin", :salt, :hash, TRUE)
|
||||
ON CONFLICT DO UPDATE SET password_hash = :hash
|
||||
WHERE username = "admin";`,
|
||||
sql.Named("salt", salt),
|
||||
sql.Named("hash", hash),
|
||||
); err == nil {
|
||||
AdvertiseAdminPassword(password.String())
|
||||
} else {
|
||||
return fmt.Errorf("failed to set initial admin password: %w", err)
|
||||
}
|
||||
func (db *DB) TouchAccount(account *model.Account) error {
|
||||
now := time.Now().UTC()
|
||||
_, err := db.Exec(`UPDATE accounts SET last_login = ? WHERE id = ?`, now.Unix(), account.Id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update last_login for user %s: %w", account.Username, err)
|
||||
}
|
||||
account.LastLogin = now
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue