Add an admin flag to users

This is preparatory work for letting some users access admin-exclusive
service commands, such as creating new users.

This adds a boolean admin flag to the User schema. Old users will stay
non-admin after the DB migration.
This commit is contained in:
delthas 2020-06-07 01:22:54 +02:00 committed by Simon Ser
parent ed943f5451
commit d1b4faa529

21
db.go
View File

@ -13,6 +13,7 @@ type User struct {
Created bool Created bool
Username string Username string
Password string // hashed Password string // hashed
Admin bool
} }
type SASL struct { type SASL struct {
@ -61,7 +62,8 @@ type Channel struct {
const schema = ` const schema = `
CREATE TABLE User ( CREATE TABLE User (
username VARCHAR(255) PRIMARY KEY, username VARCHAR(255) PRIMARY KEY,
password VARCHAR(255) NOT NULL password VARCHAR(255) NOT NULL,
admin INTEGER NOT NULL DEFAULT 0
); );
CREATE TABLE Network ( CREATE TABLE Network (
@ -100,6 +102,7 @@ var migrations = []string{
"ALTER TABLE Channel ADD COLUMN detached INTEGER NOT NULL DEFAULT 0", "ALTER TABLE Channel ADD COLUMN detached INTEGER NOT NULL DEFAULT 0",
"ALTER TABLE Network ADD COLUMN sasl_external_cert BLOB DEFAULT NULL", "ALTER TABLE Network ADD COLUMN sasl_external_cert BLOB DEFAULT NULL",
"ALTER TABLE Network ADD COLUMN sasl_external_key BLOB DEFAULT NULL", "ALTER TABLE Network ADD COLUMN sasl_external_key BLOB DEFAULT NULL",
"ALTER TABLE User ADD COLUMN admin INTEGER NOT NULL DEFAULT 0",
} }
type DB struct { type DB struct {
@ -187,7 +190,7 @@ func (db *DB) ListUsers() ([]User, error) {
db.lock.RLock() db.lock.RLock()
defer db.lock.RUnlock() defer db.lock.RUnlock()
rows, err := db.db.Query("SELECT username, password FROM User") rows, err := db.db.Query("SELECT username, password, admin FROM User")
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -197,7 +200,7 @@ func (db *DB) ListUsers() ([]User, error) {
for rows.Next() { for rows.Next() {
var user User var user User
var password *string var password *string
if err := rows.Scan(&user.Username, &password); err != nil { if err := rows.Scan(&user.Username, &password, &user.Admin); err != nil {
return nil, err return nil, err
} }
user.Created = true user.Created = true
@ -218,8 +221,8 @@ func (db *DB) GetUser(username string) (*User, error) {
user := &User{Created: true, Username: username} user := &User{Created: true, Username: username}
var password *string var password *string
row := db.db.QueryRow("SELECT password FROM User WHERE username = ?", username) row := db.db.QueryRow("SELECT password, admin FROM User WHERE username = ?", username)
if err := row.Scan(&password); err != nil { if err := row.Scan(&password, &user.Admin); err != nil {
return nil, err return nil, err
} }
user.Password = fromStringPtr(password) user.Password = fromStringPtr(password)
@ -234,11 +237,11 @@ func (db *DB) StoreUser(user *User) error {
var err error var err error
if user.Created { if user.Created {
_, err = db.db.Exec("UPDATE User SET password = ? WHERE username = ?", _, err = db.db.Exec("UPDATE User SET password = ?, admin = ? WHERE username = ?",
password, user.Username) password, user.Admin, user.Username)
} else { } else {
_, err = db.db.Exec("INSERT INTO User(username, password) VALUES (?, ?)", _, err = db.db.Exec("INSERT INTO User(username, password, admin) VALUES (?, ?, ?)",
user.Username, password) user.Username, password, user.Admin)
if err == nil { if err == nil {
user.Created = true user.Created = true
} }