cerca

lean forum software (pmc local branch)
Log | Files | Refs | README | LICENSE

commit a3d3fe3e2d3e28beabe6bebd1faf62c7132b9bf6
parent 53919f5c7f775f67fe015b3f18e1c9c82f4df20f
Author: cblgh <cblgh@cblgh.org>
Date:   Mon, 31 Jul 2023 14:47:23 +0200

create admin utility: add-user

Diffstat:
Acmd/admin-add-user/main.go | 112+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 112 insertions(+), 0 deletions(-)

diff --git a/cmd/admin-add-user/main.go b/cmd/admin-add-user/main.go @@ -0,0 +1,112 @@ +package main + +import ( + "cerca/crypto" + "cerca/database" + "cerca/util" + "flag" + "fmt" + "os" +) + +type UserInfo struct { + Username, Password, Keypair string +} + +func createUser (username, password string, db *database.DB) UserInfo { + ed := util.Describe("admin reset") + // make sure username is not registered already + var err error + if exists, err := db.CheckUsernameExists(username); err != nil { + complain("Database had a problem when checking username") + } else if exists { + complain("Username %s appears to already exist, please pick another name", username) + } + var hash string + if hash, err = crypto.HashPassword(password); err != nil { + complain("Database had a problem when hashing password") + } + var userID int + if userID, err = db.CreateUser(username, hash); err != nil { + complain("Error in db when creating user") + } + // log where the registration is coming from, in the case of indirect invites && for curiosity + err = db.AddRegistration(userID, "https://example.com/admin-add-user") + if err = ed.Eout(err, "add registration"); err != nil { + complain("Database had a problem saving user registration location") + } + // generate and pass public keypair + keypair, err := crypto.GenerateKeypair() + ed.Check(err, "generate keypair") + // record generated pubkey in database for eventual later use + pub, err := keypair.PublicString() + if err = ed.Eout(err, "convert pubkey to string"); err != nil { + complain("Can't convert pubkey to string") + } + ed.Check(err, "stringify pubkey") + err = db.AddPubkey(userID, pub) + if err = ed.Eout(err, "insert pubkey in db"); err != nil { + complain("Database had a problem saving user registration") + } + kpJson, err := keypair.Marshal() + ed.Check(err, "marshal keypair") + return UserInfo{Username: username, Password: password, Keypair: string(kpJson)} +} + +func inform(msg string, args ...interface{}) { + if len(args) > 0 { + fmt.Printf("admin-add-user: %s\n", fmt.Sprintf(msg, args...)) + } else { + fmt.Printf("admin-add-user: %s\n", msg) + } +} + +func complain(msg string, args ...interface{}) { + if len(args) > 0 { + inform(msg, args) + } else { + inform(msg) + } + os.Exit(0) +} + +func main() { + var username string + var forumDomain string + var keypairFlag bool + var dbPath string + flag.BoolVar(&keypairFlag, "keypair", false, "output the keypair") + flag.StringVar(&forumDomain, "url", "https://forum.merveilles.town", "root url to forum, referenced in output") + flag.StringVar(&username, "username", "", "username whose credentials should be reset") + flag.StringVar(&dbPath, "database", "./data/forum.db", "full path to the forum database; e.g. ./data/forum.db") + flag.Parse() + + usage := `usage + admin-add-user --url https://forum.merveilles.town --database ./data/forum.db --username <username to create account for> + admin-add-user --help for more information + ` + + if username == "" { + complain(usage) + } + + // check if database exists! we dont wanna create a new db in this case ':) + if !database.CheckExists(dbPath) { + complain("couldn't find database at %s", dbPath) + } + + db := database.InitDB(dbPath) + newPassword := crypto.GeneratePassword() + info := createUser(username, newPassword, &db) + + loginRoute := fmt.Sprintf("%s/login", forumDomain) + resetRoute := fmt.Sprintf("%s/reset", forumDomain) + + inform("[user]\n%s", username) + inform("[password]\n%s", newPassword) + if keypairFlag { + inform("[keypair]\n%s", info.Keypair) + } + inform("Please login at %s\n", loginRoute) + inform("After logging in, visit %s to reset your password", resetRoute) +}