diff --git a/README.md b/README.md index 0873ff6..81bc52f 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ need to be up for this, making this ideal for some offline maintenance. - `createInvite`: Creates an invite code to register new accounts. - `purgeInvites`: Deletes all available invite codes. +- `listAccounts`: Lists all active accounts. - `deleteAccount `: Deletes an account with a given `username`. ## database diff --git a/controller/account.go b/controller/account.go index 362e297..3547d35 100644 --- a/controller/account.go +++ b/controller/account.go @@ -11,6 +11,17 @@ import ( "github.com/jmoiron/sqlx" ) +func GetAllAccounts(db *sqlx.DB) ([]model.Account, error) { + var accounts = []model.Account{} + + err := db.Select(&accounts, "SELECT * FROM account ORDER BY created_at ASC") + if err != nil { + return nil, err + } + + return accounts, nil +} + func GetAccount(db *sqlx.DB, username string) (*model.Account, error) { var account = model.Account{} diff --git a/main.go b/main.go index 2f0cb43..fb83494 100644 --- a/main.go +++ b/main.go @@ -98,6 +98,27 @@ func main() { fmt.Printf("Invites deleted successfully.\n") return + case "listAccounts": + accounts, err := controller.GetAllAccounts(global.DB) + if err != nil { + fmt.Fprintf(os.Stderr, "Failed to fetch accounts: %v\n", err) + os.Exit(1) + } + + for _, account := range accounts { + fmt.Printf( + "User: %s\n" + + "\tID: %s\n" + + "\tEmail: %s\n" + + "\tCreated: %s\n", + account.Username, + account.ID, + account.Email, + account.CreatedAt, + ) + } + return + case "deleteAccount": if len(os.Args) < 2 { fmt.Fprintf(os.Stderr, "FATAL: Account name not specified for -deleteAccount\n") @@ -108,7 +129,7 @@ func main() { account, err := controller.GetAccount(global.DB, username) if err != nil { - fmt.Fprintf(os.Stderr, "Failed to fetch account \"%s\": %s\n", username, err.Error()) + fmt.Fprintf(os.Stderr, "Failed to fetch account \"%s\": %v\n", username, err) os.Exit(1) } @@ -135,10 +156,12 @@ func main() { } - fmt.Printf( + // command help + fmt.Print( "Available commands:\n\n" + "createInvite:\n\tCreates an invite code to register new accounts.\n" + "purgeInvites:\n\tDeletes all available invite codes.\n" + + "listAccounts:\n\tLists all active accounts.\n", "deleteAccount :\n\tDeletes an account with a given `username`.\n", ) return diff --git a/model/account.go b/model/account.go index 03e95c5..031cae9 100644 --- a/model/account.go +++ b/model/account.go @@ -1,12 +1,16 @@ package model +import "time" + type ( Account struct { - ID string `json:"id" db:"id"` - Username string `json:"username" db:"username"` - Password string `json:"password" db:"password"` - Email string `json:"email" db:"email"` - AvatarURL string `json:"avatar_url" db:"avatar_url"` + ID string `json:"id" db:"id"` + Username string `json:"username" db:"username"` + Password string `json:"password" db:"password"` + Email string `json:"email" db:"email"` + AvatarURL string `json:"avatar_url" db:"avatar_url"` + CreatedAt time.Time `json:"created_at" db:"created_at"` + Privileges []AccountPrivilege `json:"privileges"` } diff --git a/schema_migration/000-init.sql b/schema_migration/000-init.sql index cd11a5e..00a7eb2 100644 --- a/schema_migration/000-init.sql +++ b/schema_migration/000-init.sql @@ -16,7 +16,8 @@ CREATE TABLE arimelody.account ( username text NOT NULL UNIQUE, password text NOT NULL, email text, - avatar_url text + avatar_url text, + created_at TIMESTAMP DEFAULT current_timestamp ); ALTER TABLE arimelody.account ADD CONSTRAINT account_pk PRIMARY KEY (id); diff --git a/schema_migration/001-pre-versioning.sql b/schema_migration/001-pre-versioning.sql index fc730a0..8f5e210 100644 --- a/schema_migration/001-pre-versioning.sql +++ b/schema_migration/001-pre-versioning.sql @@ -22,7 +22,8 @@ CREATE TABLE arimelody.account ( username text NOT NULL UNIQUE, password text NOT NULL, email text, - avatar_url text + avatar_url text, + created_at TIMESTAMP DEFAULT current_timestamp ); ALTER TABLE arimelody.account ADD CONSTRAINT account_pk PRIMARY KEY (id);