main.go (3079B)
1 package main 2 3 import ( 4 "cerca/constants" 5 "cerca/crypto" 6 "cerca/database" 7 "cerca/util" 8 "flag" 9 "fmt" 10 "os" 11 ) 12 13 type UserInfo struct { 14 ID int 15 Username, Password string 16 } 17 18 func createUser(username, password string, db *database.DB) UserInfo { 19 ed := util.Describe("admin reset") 20 // make sure username is not registered already 21 var err error 22 if exists, err := db.CheckUsernameExists(username); err != nil { 23 complain("Database had a problem when checking username") 24 } else if exists { 25 complain("Username %s appears to already exist, please pick another name", username) 26 } 27 var hash string 28 if hash, err = crypto.HashPassword(password); err != nil { 29 complain("Database had a problem when hashing password") 30 } 31 var userID int 32 if userID, err = db.CreateUser(username, hash); err != nil { 33 complain("Error in db when creating user") 34 } 35 // log where the registration is coming from, in the case of indirect invites && for curiosity 36 err = db.AddRegistration(userID, "https://example.com/admin-add-user") 37 if err = ed.Eout(err, "add registration"); err != nil { 38 complain("Database had a problem saving user registration location") 39 } 40 return UserInfo{ID: userID, Username: username, Password: password} 41 } 42 43 func inform(msg string, args ...interface{}) { 44 if len(args) > 0 { 45 fmt.Printf("%s\n", fmt.Sprintf(msg, args...)) 46 } else { 47 fmt.Printf("%s\n", msg) 48 } 49 } 50 51 func complain(msg string, args ...interface{}) { 52 if len(args) > 0 { 53 inform(msg, args) 54 } else { 55 inform(msg) 56 } 57 os.Exit(0) 58 } 59 60 func main() { 61 var username string 62 var forumDomain string 63 var dbPath string 64 flag.StringVar(&forumDomain, "url", "https://forum.merveilles.town", "root url to forum, referenced in output") 65 flag.StringVar(&username, "username", "", "username whose credentials should be reset") 66 flag.StringVar(&dbPath, "database", "./data/forum.db", "full path to the forum database; e.g. ./data/forum.db") 67 flag.Parse() 68 69 usage := `usage 70 admin-add-user --url https://forum.merveilles.town --database ./data/forum.db --username <username to create account for> 71 admin-add-user --help for more information 72 ` 73 74 if username == "" { 75 complain(usage) 76 } 77 78 // check if database exists! we dont wanna create a new db in this case ':) 79 if !database.CheckExists(dbPath) { 80 complain("couldn't find database at %s", dbPath) 81 } 82 83 db := database.InitDB(dbPath) 84 85 newPassword := crypto.GeneratePassword() 86 userInfo := createUser(username, newPassword, &db) 87 88 // log cmd actions just as admin web-actions are logged 89 systemUserid := db.GetSystemUserid() 90 err := db.AddModerationLog(systemUserid, userInfo.ID, constants.MODLOG_ADMIN_ADD_USER) 91 if err != nil { 92 complain("adding mod log for adding new user failed (%w)", err) 93 } 94 95 loginRoute := fmt.Sprintf("%s/login", forumDomain) 96 resetRoute := fmt.Sprintf("%s/reset", forumDomain) 97 98 inform("[user]\n%s", username) 99 inform("[password]\n%s", newPassword) 100 inform("Please login at %s\n", loginRoute) 101 inform("After logging in, visit %s to reset your password", resetRoute) 102 inform("Admin action has been logged to /moderations") 103 }