Add display names for app users
This commit is contained in:
parent
6e7aa87de6
commit
b625c95c29
3 changed files with 92 additions and 35 deletions
|
|
@ -41,6 +41,7 @@ type Account struct {
|
|||
type AppUser struct {
|
||||
ID int64
|
||||
Username string
|
||||
DisplayName string
|
||||
Role string
|
||||
Active bool
|
||||
PasswordHash string
|
||||
|
|
@ -119,6 +120,7 @@ func ConnectDB() error {
|
|||
`CREATE TABLE IF NOT EXISTS app_users(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
username TEXT NOT NULL UNIQUE,
|
||||
display_name TEXT NOT NULL DEFAULT '',
|
||||
password_hash TEXT NOT NULL,
|
||||
role TEXT NOT NULL DEFAULT 'user',
|
||||
active INTEGER NOT NULL DEFAULT 1,
|
||||
|
|
@ -139,6 +141,41 @@ func ConnectDB() error {
|
|||
}
|
||||
}
|
||||
DB = db
|
||||
if err := ensureAppUserColumns(); err != nil {
|
||||
_ = db.Close()
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ensureAppUserColumns() error {
|
||||
hasDisplayName := false
|
||||
rows, err := DB.Query(`PRAGMA table_info(app_users)`)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
var cid int
|
||||
var name, typ string
|
||||
var notNull int
|
||||
var defaultValue any
|
||||
var pk int
|
||||
if err := rows.Scan(&cid, &name, &typ, ¬Null, &defaultValue, &pk); err != nil {
|
||||
return err
|
||||
}
|
||||
if name == "display_name" {
|
||||
hasDisplayName = true
|
||||
}
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
if !hasDisplayName {
|
||||
if _, err := DB.Exec(`ALTER TABLE app_users ADD COLUMN display_name TEXT NOT NULL DEFAULT ''`); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -149,7 +186,7 @@ func CountAppUsers() (int, error) {
|
|||
}
|
||||
|
||||
func ListAppUsers() ([]AppUser, error) {
|
||||
rows, err := DB.Query(`SELECT id, username, password_hash, role, active FROM app_users ORDER BY username`)
|
||||
rows, err := DB.Query(`SELECT id, username, display_name, password_hash, role, active FROM app_users ORDER BY username`)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -166,30 +203,32 @@ func ListAppUsers() ([]AppUser, error) {
|
|||
}
|
||||
|
||||
func GetAppUser(username string) (AppUser, error) {
|
||||
row := DB.QueryRow(`SELECT id, username, password_hash, role, active FROM app_users WHERE username=?`, username)
|
||||
row := DB.QueryRow(`SELECT id, username, display_name, password_hash, role, active FROM app_users WHERE username=?`, username)
|
||||
return scanAppUser(row)
|
||||
}
|
||||
|
||||
func GetAppUserByID(id int64) (AppUser, error) {
|
||||
row := DB.QueryRow(`SELECT id, username, password_hash, role, active FROM app_users WHERE id=?`, id)
|
||||
row := DB.QueryRow(`SELECT id, username, display_name, password_hash, role, active FROM app_users WHERE id=?`, id)
|
||||
return scanAppUser(row)
|
||||
}
|
||||
|
||||
func SaveAppUser(username, passwordHash, role string, active bool) error {
|
||||
func SaveAppUser(username, displayName, passwordHash, role string, active bool) error {
|
||||
displayName = strings.TrimSpace(displayName)
|
||||
role = normalizeRole(role)
|
||||
if passwordHash == "" {
|
||||
_, err := DB.Exec(`UPDATE app_users SET role=?, active=?, updated_at=CURRENT_TIMESTAMP WHERE username=?`,
|
||||
role, boolInt(active), username)
|
||||
_, err := DB.Exec(`UPDATE app_users SET display_name=?, role=?, active=?, updated_at=CURRENT_TIMESTAMP WHERE username=?`,
|
||||
displayName, role, boolInt(active), username)
|
||||
return err
|
||||
}
|
||||
_, err := DB.Exec(`INSERT INTO app_users(username, password_hash, role, active)
|
||||
VALUES(?,?,?,?)
|
||||
_, err := DB.Exec(`INSERT INTO app_users(username, display_name, password_hash, role, active)
|
||||
VALUES(?,?,?,?,?)
|
||||
ON CONFLICT(username) DO UPDATE SET
|
||||
display_name=excluded.display_name,
|
||||
password_hash=excluded.password_hash,
|
||||
role=excluded.role,
|
||||
active=excluded.active,
|
||||
updated_at=CURRENT_TIMESTAMP`,
|
||||
username, passwordHash, role, boolInt(active))
|
||||
username, displayName, passwordHash, role, boolInt(active))
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -209,7 +248,7 @@ func DeleteSession(token string) error {
|
|||
}
|
||||
|
||||
func SessionUser(token string) (AppUser, error) {
|
||||
row := DB.QueryRow(`SELECT u.id, u.username, u.password_hash, u.role, u.active
|
||||
row := DB.QueryRow(`SELECT u.id, u.username, u.display_name, u.password_hash, u.role, u.active
|
||||
FROM app_sessions s JOIN app_users u ON u.id=s.user_id
|
||||
WHERE s.token=? AND s.expires_at > CURRENT_TIMESTAMP AND u.active=1`, token)
|
||||
return scanAppUser(row)
|
||||
|
|
@ -351,7 +390,7 @@ func normalizeAccount(a *Account) {
|
|||
func scanAppUser(s appUserScanner) (AppUser, error) {
|
||||
var u AppUser
|
||||
var active int
|
||||
err := s.Scan(&u.ID, &u.Username, &u.PasswordHash, &u.Role, &active)
|
||||
err := s.Scan(&u.ID, &u.Username, &u.DisplayName, &u.PasswordHash, &u.Role, &active)
|
||||
u.Role = normalizeRole(u.Role)
|
||||
u.Active = active != 0
|
||||
return u, err
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue