You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
2.9 KiB
159 lines
2.9 KiB
package main |
|
|
|
import ( |
|
"database/sql" |
|
"errors" |
|
"log" |
|
"strings" |
|
|
|
_ "github.com/mattn/go-sqlite3" |
|
) |
|
|
|
// encodePrivs encodes priv map into DB-ready string |
|
func encodePrivs(privs map[string]bool) string { |
|
lenP := 0 |
|
for priv := range privs { |
|
if privs[priv] { |
|
lenP++ |
|
} |
|
} |
|
|
|
ps := make([]string, lenP) |
|
|
|
i := 0 |
|
for priv := range privs { |
|
if privs[priv] { |
|
ps[i] = priv |
|
|
|
i++ |
|
} |
|
} |
|
|
|
r := strings.Join(ps, "|") |
|
|
|
return r |
|
} |
|
|
|
// decodePrivs decodes DB-ready string into priv map |
|
func decodePrivs(s string) map[string]bool { |
|
ps := strings.Split(s, "|") |
|
|
|
r := make(map[string]bool) |
|
|
|
for i := range ps { |
|
if ps[i] != "" { |
|
r[ps[i]] = true |
|
} |
|
} |
|
|
|
return r |
|
} |
|
|
|
// addPrivItem inserts a priv DB entry |
|
func addPrivItem(db *sql.DB, name string) error { |
|
_, err := db.Exec(`INSERT INTO privileges ( |
|
name, |
|
privileges |
|
) VALUES ( |
|
?, |
|
"" |
|
);`, name) |
|
return err |
|
} |
|
|
|
// modPrivItem updates a priv DB entry |
|
func modPrivItem(db *sql.DB, name, privs string) error { |
|
_, err := db.Exec(`UPDATE privileges SET privileges = ? WHERE name = ?;`, privs, name) |
|
return err |
|
} |
|
|
|
// readPrivItem selects and reads a priv DB entry |
|
func readPrivItem(db *sql.DB, name string) (string, error) { |
|
var r string |
|
err := db.QueryRow(`SELECT privileges FROM privileges WHERE name = ?;`, name).Scan(&r) |
|
if err != nil && !errors.Is(err, sql.ErrNoRows) { |
|
return "", err |
|
} |
|
|
|
return r, err |
|
} |
|
|
|
// Privs returns the privileges of a player |
|
func Privs(name string) (map[string]bool, error) { |
|
db, err := initAuthDB() |
|
if err != nil { |
|
return nil, err |
|
} |
|
defer db.Close() |
|
|
|
eprivs, err := readPrivItem(db, name) |
|
if err != nil { |
|
return nil, err |
|
} |
|
|
|
return decodePrivs(eprivs), nil |
|
} |
|
|
|
// Privs returns the privileges of a Conn |
|
func (c *Conn) Privs() (map[string]bool, error) { |
|
return Privs(c.Username()) |
|
} |
|
|
|
// SetPrivs sets the privileges of a player |
|
func SetPrivs(name string, privs map[string]bool) error { |
|
db, err := initAuthDB() |
|
if err != nil { |
|
return err |
|
} |
|
defer db.Close() |
|
|
|
err = modPrivItem(db, name, encodePrivs(privs)) |
|
if err != nil { |
|
return err |
|
} |
|
|
|
return nil |
|
} |
|
|
|
// SetPrivs sets the privileges of a Conn |
|
func (c *Conn) SetPrivs(privs map[string]bool) error { |
|
return SetPrivs(c.Username(), privs) |
|
} |
|
|
|
// CheckPrivs reports if a player has all of the specified privileges |
|
func CheckPrivs(name string, req map[string]bool) (bool, error) { |
|
privs, err := Privs(name) |
|
if err != nil { |
|
return false, err |
|
} |
|
|
|
for priv := range req { |
|
if req[priv] && !privs[priv] { |
|
return false, nil |
|
} |
|
} |
|
|
|
return true, nil |
|
} |
|
|
|
// CheckPrivs reports if a Conn has all of the specified privileges |
|
func (c *Conn) CheckPrivs(req map[string]bool) (bool, error) { |
|
return CheckPrivs(c.Username(), req) |
|
} |
|
|
|
func init() { |
|
if admin, ok := ConfKey("admin").(string); ok { |
|
privs, err := Privs(admin) |
|
if err != nil { |
|
log.Print(err) |
|
return |
|
} |
|
|
|
privs["privs"] = true |
|
|
|
if err = SetPrivs(admin, privs); err != nil { |
|
log.Print(err) |
|
return |
|
} |
|
} |
|
}
|
|
|