2021-01-24 05:00:26 -08:00
|
|
|
package main
|
2021-01-07 14:29:46 -08:00
|
|
|
|
|
|
|
import (
|
|
|
|
"database/sql"
|
2021-01-12 12:25:43 -08:00
|
|
|
"log"
|
2021-01-09 03:26:30 -08:00
|
|
|
"strings"
|
2021-01-18 13:08:22 -08:00
|
|
|
|
|
|
|
_ "github.com/mattn/go-sqlite3"
|
2021-01-07 14:29:46 -08:00
|
|
|
)
|
|
|
|
|
|
|
|
// 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++
|
|
|
|
}
|
|
|
|
}
|
2021-01-09 03:26:30 -08:00
|
|
|
|
2021-01-07 14:29:46 -08:00
|
|
|
ps := make([]string, lenP)
|
2021-01-09 03:26:30 -08:00
|
|
|
|
2021-01-07 14:29:46 -08:00
|
|
|
i := 0
|
|
|
|
for priv := range privs {
|
|
|
|
if privs[priv] {
|
|
|
|
ps[i] = priv
|
2021-01-09 03:26:30 -08:00
|
|
|
|
2021-01-07 14:29:46 -08:00
|
|
|
i++
|
|
|
|
}
|
|
|
|
}
|
2021-01-09 03:26:30 -08:00
|
|
|
|
2021-01-07 14:29:46 -08:00
|
|
|
r := strings.Join(ps, "|")
|
2021-01-09 03:26:30 -08:00
|
|
|
|
2021-01-07 14:29:46 -08:00
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
// decodePrivs decodes DB-ready string into priv map
|
|
|
|
func decodePrivs(s string) map[string]bool {
|
|
|
|
ps := strings.Split(s, "|")
|
2021-01-09 03:26:30 -08:00
|
|
|
|
2021-01-07 14:29:46 -08:00
|
|
|
r := make(map[string]bool)
|
2021-01-09 03:26:30 -08:00
|
|
|
|
2021-01-07 14:29:46 -08:00
|
|
|
for i := range ps {
|
2021-01-10 12:51:26 -08:00
|
|
|
if ps[i] != "" {
|
|
|
|
r[ps[i]] = true
|
|
|
|
}
|
2021-01-07 14:29:46 -08:00
|
|
|
}
|
2021-01-09 03:26:30 -08:00
|
|
|
|
2021-01-07 14:29:46 -08:00
|
|
|
return r
|
|
|
|
}
|
|
|
|
|
|
|
|
// addPrivItem inserts a priv DB entry
|
|
|
|
func addPrivItem(db *sql.DB, name string) error {
|
2021-04-01 01:28:28 -07:00
|
|
|
_, err := db.Exec(`INSERT INTO privileges (
|
2021-01-07 14:29:46 -08:00
|
|
|
name,
|
|
|
|
privileges
|
|
|
|
) VALUES (
|
|
|
|
?,
|
|
|
|
""
|
2021-04-01 01:28:28 -07:00
|
|
|
);`, name)
|
2021-04-01 06:10:04 -07:00
|
|
|
return err
|
2021-01-07 14:29:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// modPrivItem updates a priv DB entry
|
|
|
|
func modPrivItem(db *sql.DB, name, privs string) error {
|
2021-04-01 01:28:28 -07:00
|
|
|
_, err := db.Exec(`UPDATE privileges SET privileges = ? WHERE name = ?;`, name)
|
2021-04-01 06:10:04 -07:00
|
|
|
return err
|
2021-01-07 14:29:46 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// readPrivItem selects and reads a priv DB entry
|
|
|
|
func readPrivItem(db *sql.DB, name string) (string, error) {
|
|
|
|
var r string
|
2021-04-01 01:28:28 -07:00
|
|
|
err := db.QueryRow(`SELECT privileges FROM privileges WHERE name = ?;`, name).Scan(&r)
|
2021-03-06 07:03:18 -08:00
|
|
|
return r, err
|
2021-01-07 14:29:46 -08:00
|
|
|
}
|
2021-01-12 12:25:43 -08:00
|
|
|
|
2021-03-20 10:46:32 -07:00
|
|
|
// Privs returns the privileges of a player
|
|
|
|
func Privs(name string) (map[string]bool, error) {
|
2021-01-14 04:40:31 -08:00
|
|
|
db, err := initAuthDB()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer db.Close()
|
|
|
|
|
2021-03-20 10:46:32 -07:00
|
|
|
eprivs, err := readPrivItem(db, name)
|
2021-01-14 04:40:31 -08:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return decodePrivs(eprivs), nil
|
|
|
|
}
|
|
|
|
|
2021-03-29 09:57:30 -07:00
|
|
|
// Privs returns the privileges of a Conn
|
|
|
|
func (c *Conn) Privs() (map[string]bool, error) {
|
|
|
|
return Privs(c.Username())
|
2021-03-20 10:46:32 -07:00
|
|
|
}
|
|
|
|
|
2021-03-29 09:57:30 -07:00
|
|
|
// SetPrivs sets the privileges of a player
|
2021-03-20 10:46:32 -07:00
|
|
|
func SetPrivs(name string, privs map[string]bool) error {
|
2021-01-14 04:40:31 -08:00
|
|
|
db, err := initAuthDB()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer db.Close()
|
|
|
|
|
2021-03-20 10:46:32 -07:00
|
|
|
err = modPrivItem(db, name, encodePrivs(privs))
|
2021-01-14 04:40:31 -08:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-03-29 09:57:30 -07:00
|
|
|
// SetPrivs sets the privileges of a Conn
|
|
|
|
func (c *Conn) SetPrivs(privs map[string]bool) error {
|
|
|
|
return SetPrivs(c.Username(), privs)
|
2021-03-20 10:46:32 -07:00
|
|
|
}
|
|
|
|
|
2021-03-29 09:57:30 -07:00
|
|
|
// 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)
|
2021-01-14 04:40:31 -08:00
|
|
|
if err != nil {
|
|
|
|
return false, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for priv := range req {
|
|
|
|
if req[priv] && !privs[priv] {
|
2021-03-29 09:57:30 -07:00
|
|
|
return false, nil
|
2021-01-14 04:40:31 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-29 09:57:30 -07:00
|
|
|
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)
|
2021-01-14 04:40:31 -08:00
|
|
|
}
|
2021-01-14 12:37:03 -08:00
|
|
|
|
|
|
|
func init() {
|
2021-03-09 13:23:41 -08:00
|
|
|
if admin, ok := ConfKey("admin").(string); ok {
|
2021-01-14 12:37:03 -08:00
|
|
|
db, err := initAuthDB()
|
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2021-01-19 09:57:58 -08:00
|
|
|
eprivs, err := readPrivItem(db, admin)
|
2021-01-14 12:37:03 -08:00
|
|
|
if err != nil {
|
|
|
|
log.Print(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
privs := decodePrivs(eprivs)
|
|
|
|
privs["privs"] = true
|
|
|
|
|
|
|
|
newprivs := encodePrivs(privs)
|
|
|
|
|
2021-01-19 09:57:58 -08:00
|
|
|
modPrivItem(db, admin, newprivs)
|
2021-01-14 12:37:03 -08:00
|
|
|
}
|
|
|
|
}
|