commit 87fa52bd7d03ff40b867d1fe8c522903226d4cdb
parent 391ef20c129638b3e67594f8182633120dea67de
Author: cblgh <cblgh@cblgh.org>
Date: Fri, 15 Dec 2023 17:48:59 +0100
add system user CERCA_CMD for logging cmd admin actions on host
Diffstat:
4 files changed, 65 insertions(+), 31 deletions(-)
diff --git a/cmd/add-admin/main.go b/cmd/add-admin/main.go
@@ -2,6 +2,7 @@ package main
import (
"cerca/database"
+ "cerca/constants"
"flag"
"fmt"
"os"
@@ -34,7 +35,7 @@ func main() {
flag.Parse()
usage := `usage
- add-admin --username <username to make admin> --url <rool url to forum>
+ add-admin --username <username to make admin> --url <rool url to forum> --database ./data/forum.db
add-admin --help for more information
`
@@ -56,11 +57,19 @@ func main() {
complain("username %s not in database", username)
}
inform("Attempting to make %s (id %d) admin...", username, userid)
- // TODO (2023-12-12): log cmd actions just as admin web-actions are logged
err = db.AddAdmin(userid)
if err != nil {
complain("Something went wrong: %s", err)
}
+
+ // log cmd actions just as admin web-actions are logged
+ systemUserid := db.GetSystemUserid()
+ err = db.AddModerationLog(systemUserid, userid, constants.MODLOG_ADMIN_MAKE)
+ if err != nil {
+ complain("adding mod log for adding new admin failed (%w)", err)
+ }
+
inform("Successfully added %s (id %d) as an admin", username, userid)
inform("Please visit %s for all your administration needs (changing usernames, resetting passwords, deleting user accounts)", adminRoute)
+ inform("Admin action has been logged to /moderations")
}
diff --git a/cmd/admin-add-user/main.go b/cmd/admin-add-user/main.go
@@ -3,6 +3,7 @@ package main
import (
"cerca/crypto"
"cerca/database"
+ "cerca/constants"
"cerca/util"
"flag"
"fmt"
@@ -10,6 +11,7 @@ import (
)
type UserInfo struct {
+ ID int
Username, Password string
}
@@ -35,7 +37,7 @@ func createUser (username, password string, db *database.DB) UserInfo {
if err = ed.Eout(err, "add registration"); err != nil {
complain("Database had a problem saving user registration location")
}
- return UserInfo{Username: username, Password: password}
+ return UserInfo{ID: userID, Username: username, Password: password}
}
func inform(msg string, args ...interface{}) {
@@ -79,8 +81,16 @@ func main() {
}
db := database.InitDB(dbPath)
+
newPassword := crypto.GeneratePassword()
- _ = createUser(username, newPassword, &db)
+ userInfo := createUser(username, newPassword, &db)
+
+ // log cmd actions just as admin web-actions are logged
+ systemUserid := db.GetSystemUserid()
+ err := db.AddModerationLog(systemUserid, userInfo.ID, constants.MODLOG_ADMIN_ADD_USER)
+ if err != nil {
+ complain("adding mod log for adding new user failed (%w)", err)
+ }
loginRoute := fmt.Sprintf("%s/login", forumDomain)
resetRoute := fmt.Sprintf("%s/reset", forumDomain)
@@ -89,4 +99,5 @@ func main() {
inform("[password]\n%s", newPassword)
inform("Please login at %s\n", loginRoute)
inform("After logging in, visit %s to reset your password", resetRoute)
+ inform("Admin action has been logged to /moderations")
}
diff --git a/cmd/admin-reset/main.go b/cmd/admin-reset/main.go
@@ -2,7 +2,7 @@ package main
import (
"cerca/database"
- "cerca/util"
+ "cerca/constants"
"flag"
"fmt"
"os"
@@ -26,29 +26,18 @@ func complain(msg string, args ...interface{}) {
}
func main() {
- var keypairFlag bool
- var passwordFlag bool
var username string
var dbPath string
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.BoolVar(&keypairFlag, "keypair", false, "reset the keypair")
- flag.BoolVar(&passwordFlag, "password", false, "reset the password. if true generates a random new password")
flag.Parse()
usage := `usage
- admin-reset --database ./data/forum.db --username <username to reset> [--keypair, --password]
+ admin-reset --database ./data/forum.db --username <username to reset>
admin-reset --help for more information
- examples:
- # only reset the keypair, leaving the password intact
- ./admin-reset --database ../../testdata/forum.db --username bambas --keypair
-
- # reset password only
- ./admin-reset --database ../../testdata/forum.db --username bambas --password
-
- # reset both password and keypair
- ./admin-reset --database ../../testdata/forum.db --username bambas --password --keypair
+ # example
+ ./admin-reset --database ../../testdata/forum.db --username bambas
`
if username == "" {
@@ -61,14 +50,25 @@ func main() {
}
db := database.InitDB(dbPath)
- ed := util.Describe("admin reset")
+
+ userid, err := db.GetUserID(username)
+ if err != nil {
+ complain("reset password failed (%w)", err)
+ }
newPassword, err := db.ResetPassword(userid)
- // TODO (2023-12-12): log cmd actions just as admin web-actions are logged
if err != nil {
complain("reset password failed (%w)", err)
}
- inform("successfully updated %s's password hash", username)
- inform("new temporary password %s", newPassword)
+ // log cmd actions just as admin web-actions are logged
+ systemUserid := db.GetSystemUserid()
+ err = db.AddModerationLog(systemUserid, userid, constants.MODLOG_RESETPW)
+ if err != nil {
+ complain("adding mod log for password reset failed (%w)", err)
+ }
+
+ inform("Successfully updated %s's password hash", username)
+ inform("New temporary password: %s", newPassword)
+ inform("Admin action has been logged to /moderations")
}
diff --git a/database/database.go b/database/database.go
@@ -50,17 +50,21 @@ func InitDB(filepath string) DB {
}
const DELETED_USER_NAME = "deleted user"
+const SYSTEM_USER_NAME = "CERCA_CMD"
+
func (d DB) makeSureDefaultUsersExist() {
ed := util.Describe("create default users")
- deletedUserExists, err := d.CheckUsernameExists(DELETED_USER_NAME)
- if err != nil {
- log.Fatalln(ed.Eout(err, "check username exists"))
- }
- if !deletedUserExists {
- passwordHash, err := crypto.HashPassword(crypto.GeneratePassword())
- _, err = d.CreateUser(DELETED_USER_NAME, passwordHash)
+ for _, defaultUser := range []string{DELETED_USER_NAME, SYSTEM_USER_NAME} {
+ userExists, err := d.CheckUsernameExists(defaultUser)
if err != nil {
- log.Fatalln(ed.Eout(err, "create deleted user"))
+ log.Fatalln(ed.Eout(err, "check username for %s exists", defaultUser))
+ }
+ if !userExists {
+ passwordHash, err := crypto.HashPassword(crypto.GeneratePassword())
+ _, err = d.CreateUser(defaultUser, passwordHash)
+ if err != nil {
+ log.Fatalln(ed.Eout(err, "create %s", defaultUser))
+ }
}
}
}
@@ -440,6 +444,16 @@ func (d DB) UpdateUserPasswordHash(userid int, newhash string) {
//
// the entry in registrations correlating to userid is removed
+func (d DB) GetSystemUserid() int {
+ ed := util.Describe("get system user id")
+ systemUserid, err := d.GetUserID(SYSTEM_USER_NAME)
+ // it should always exist
+ if err != nil {
+ log.Fatalln(ed.Eout(err, "get system user id"))
+ }
+ return systemUserid
+}
+
// if allowing deletion of post contents as well when removing account,
// userid should be used to get all posts from table posts and change the contents
// to say _deleted_