179 lines
3.6 KiB
Go
179 lines
3.6 KiB
Go
package db
|
|
|
|
import (
|
|
"errors"
|
|
"git.giftfish.de/ston1th/gowiki/pkg/core"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
var (
|
|
errUserNotFound = dbErr("user not found")
|
|
errUserExists = dbErr("user already exist")
|
|
)
|
|
|
|
func (db *DB) GetUsers() (users []core.User, err error) {
|
|
// TODO
|
|
/*users, err = db.DumpUsers()
|
|
for i := range users {
|
|
users[i].Password = ""
|
|
}*/
|
|
return
|
|
}
|
|
|
|
func (db *DB) GetUserWithoutPassword(username string) (u core.User, err error) {
|
|
u, err = db.GetUser(username)
|
|
u.Password = ""
|
|
return
|
|
}
|
|
|
|
func (db *DB) GetUser(username string) (u core.User, err error) {
|
|
err = db.users.Get(username, &u)
|
|
return
|
|
}
|
|
|
|
func (db *DB) UserExists(username string) error {
|
|
return db.users.Get(username, nil)
|
|
}
|
|
|
|
// TODO
|
|
/*func (bs *BoltStore) DumpUsers() (users []User, err error) {
|
|
var buf [][]byte
|
|
err = bs.db.View(func(tx *bolt.Tx) error {
|
|
return tx.Bucket([]byte(userTable)).ForEach(func(k, v []byte) error {
|
|
buf = append(buf, copyBuf(v))
|
|
return nil
|
|
})
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
for _, b := range buf {
|
|
u := new(User)
|
|
if err = bs.Unmarshal(b, u); err != nil {
|
|
return
|
|
}
|
|
users = append(users, *u)
|
|
}
|
|
return
|
|
}
|
|
|
|
func (bs *BoltStore) RestoreUsers(users []User) error {
|
|
return bs.db.Update(func(tx *bolt.Tx) error {
|
|
b := tx.Bucket([]byte(userTable))
|
|
err := b.ForEach(func(k, v []byte) error {
|
|
return b.Delete(k)
|
|
})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, u := range users {
|
|
v, err := bs.Marshal(u)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = b.Put([]byte(u.Username), v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
})
|
|
}*/
|
|
|
|
func (db *DB) CreateUser(username, password string, admin bool) error {
|
|
if err := db.UserExists(username); err == nil {
|
|
return errUserExists
|
|
}
|
|
hash, err := bcrypt.GenerateFromPassword(validatePassword(password), bcryptCost)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return db.users.Set(username, &core.User{
|
|
Username: username,
|
|
Password: string(hash),
|
|
Admin: admin,
|
|
})
|
|
}
|
|
|
|
func (db *DB) Login(username, password string) (u core.User, err error) {
|
|
u, err = db.GetUser(username)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if u.Locked == 3 {
|
|
err = errors.New("db: user locked")
|
|
return
|
|
}
|
|
if err = bcrypt.CompareHashAndPassword([]byte(u.Password), validatePassword(password)); err != nil {
|
|
u.Locked++
|
|
err = db.users.Set(username, u)
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = errors.New("db: wrong login")
|
|
return
|
|
}
|
|
if u.Locked > 0 {
|
|
u.Locked = 0
|
|
err = db.users.Set(username, u)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (db *DB) UnlockUser(username string) (err error) {
|
|
var u core.User
|
|
u, err = db.GetUser(username)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if u.Locked > 0 {
|
|
u.Locked = 0
|
|
err = db.users.Set(username, u)
|
|
if err != nil {
|
|
return
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
func (db *DB) UpdateUserPassword(username, password string) error {
|
|
u, err := db.GetUser(username)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
hash, err := bcrypt.GenerateFromPassword(validatePassword(password), bcryptCost)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
u.Password = string(hash)
|
|
return db.users.Set(username, u)
|
|
}
|
|
|
|
func (db *DB) AdminUpdateUser(username, password string, admin bool) error {
|
|
if username == defUser && !admin {
|
|
return errors.New("user '" + defUser + "' cannot lose admin privileges")
|
|
}
|
|
u, err := db.GetUser(username)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
u.Admin = admin
|
|
if password != "" {
|
|
hash, err := bcrypt.GenerateFromPassword(validatePassword(password), bcryptCost)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
u.Password = string(hash)
|
|
}
|
|
return db.users.Set(username, u)
|
|
}
|
|
|
|
func (db *DB) DeleteUser(username string) error {
|
|
if username == defUser {
|
|
return errors.New("user '" + defUser + "' cannot be deleted")
|
|
}
|
|
return db.users.Delete(username)
|
|
}
|