238 lines
4.8 KiB
Go
238 lines
4.8 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/pborman/uuid"
|
|
"golang.org/x/crypto/bcrypt"
|
|
)
|
|
|
|
type User struct {
|
|
Username string `json:username`
|
|
Uuid string `json:uuid`
|
|
SubSlugs []string `json:subs`
|
|
IsAdmin bool `json:admin`
|
|
}
|
|
|
|
func NewUser(un string) *User {
|
|
u := new(User)
|
|
u.Username = un
|
|
u.Uuid = uuid.New()
|
|
return u
|
|
}
|
|
|
|
/*
|
|
func (u *User) UpdateFeed() error {
|
|
for _, slug := range u.SubSlugs {
|
|
pts := strings.Split(slug, ";")
|
|
if len(pts) != 2 {
|
|
continue
|
|
}
|
|
if comic, err := m.GetComic(pts[0], pts[1]); err == nil {
|
|
comic.Update()
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
*/
|
|
|
|
func (m *model) SaveUser(u *User) error {
|
|
var err error
|
|
if err = m.openDB(); err != nil {
|
|
return err
|
|
}
|
|
defer m.closeDB()
|
|
bkt := []string{"users", u.Uuid}
|
|
if err = m.bolt.MkBucketPath(bkt); err != nil {
|
|
return err
|
|
}
|
|
if err = m.bolt.SetValue(bkt, "username", u.Username); err != nil {
|
|
return err
|
|
}
|
|
var adminVal = "false"
|
|
if u.IsAdmin {
|
|
adminVal = "true"
|
|
}
|
|
if err = m.bolt.SetValue(bkt, "admin", adminVal); err != nil {
|
|
return err
|
|
}
|
|
var newSubs []string
|
|
for _, v := range u.SubSlugs {
|
|
if strings.TrimSpace(v) != "" {
|
|
newSubs = append(newSubs, v)
|
|
}
|
|
}
|
|
slugs := strings.Join(newSubs, ",")
|
|
if err = m.bolt.SetValue(bkt, "subs", slugs); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *model) isValidUser(uid string) bool {
|
|
var err error
|
|
if err = m.openDB(); err != nil {
|
|
return false
|
|
}
|
|
defer m.closeDB()
|
|
ret := new(User)
|
|
bkt := []string{"users", uid}
|
|
ret.Uuid = uid
|
|
if ret.Username, err = m.bolt.GetValue(bkt, "username"); err != nil {
|
|
fmt.Println("Error getting username value:", err.Error())
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (m *model) GetUserByEmail(email string) (*User, error) {
|
|
if email == "" {
|
|
return nil, errors.New("No email given")
|
|
}
|
|
u := m.GetAllUsers()
|
|
for i := range u {
|
|
if u[i].Username == email {
|
|
return &u[i], nil
|
|
}
|
|
}
|
|
return nil, errors.New("No user found")
|
|
}
|
|
|
|
func (m *model) GetUser(uid string) (*User, error) {
|
|
if uid == "" {
|
|
return nil, errors.New("No user id given")
|
|
}
|
|
var err error
|
|
if err = m.openDB(); err != nil {
|
|
return nil, err
|
|
}
|
|
defer m.closeDB()
|
|
ret := new(User)
|
|
bkt := []string{"users", uid}
|
|
ret.Uuid = uid
|
|
if ret.Username, err = m.bolt.GetValue(bkt, "username"); err != nil {
|
|
fmt.Println("Error getting username value:", err.Error())
|
|
return nil, err
|
|
}
|
|
admin, _ := m.bolt.GetValue(bkt, "admin")
|
|
ret.IsAdmin = (admin == "true")
|
|
var subs string
|
|
if subs, err = m.bolt.GetValue(bkt, "subs"); err != nil {
|
|
return nil, err
|
|
}
|
|
ret.SubSlugs = strings.Split(subs, ",")
|
|
return ret, nil
|
|
}
|
|
|
|
func (m *model) SaveAllUsers(users []User) {
|
|
var err error
|
|
if err = m.openDB(); err != nil {
|
|
return
|
|
}
|
|
defer m.closeDB()
|
|
for i := range users {
|
|
m.SaveUser(&users[i])
|
|
}
|
|
}
|
|
|
|
func (m *model) LoadUsers() error {
|
|
m.Users = m.GetAllUsers()
|
|
return nil
|
|
}
|
|
|
|
func (m *model) GetAllUsers() []User {
|
|
var err error
|
|
var ret []User
|
|
if err = m.openDB(); err != nil {
|
|
return ret
|
|
}
|
|
defer m.closeDB()
|
|
|
|
uids := m.GetUserIdList()
|
|
for _, uid := range uids {
|
|
if u, e := m.GetUser(uid); e == nil {
|
|
ret = append(ret, *u)
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (m *model) GetUserByName(nm string) (*User, error) {
|
|
var err error
|
|
if err = m.openDB(); err != nil {
|
|
return nil, err
|
|
}
|
|
defer m.closeDB()
|
|
usrids := m.GetUserIdList()
|
|
for i := range usrids {
|
|
bkt := []string{"users", usrids[i]}
|
|
var tstuname string
|
|
if tstuname, _ = m.bolt.GetValue(bkt, "username"); tstuname == nm {
|
|
// Found it
|
|
return m.GetUser(usrids[i])
|
|
}
|
|
}
|
|
return nil, errors.New("No user with username " + nm + " found")
|
|
}
|
|
|
|
func (m *model) GetUserIdList() []string {
|
|
var ret []string
|
|
var err error
|
|
if err = m.openDB(); err != nil {
|
|
return ret
|
|
}
|
|
defer m.closeDB()
|
|
bkt := []string{"users"}
|
|
ret, _ = m.bolt.GetBucketList(bkt)
|
|
return ret
|
|
}
|
|
|
|
// updateUserPassword
|
|
// Takes a user id and a password
|
|
// Fails if the user doesn't exist
|
|
func (m *model) updateUserPassword(uid, password string) error {
|
|
cryptPw, cryptError := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
|
if cryptError != nil {
|
|
return cryptError
|
|
}
|
|
if _, err := m.GetUser(uid); err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := m.openDB(); err != nil {
|
|
return err
|
|
}
|
|
defer m.closeDB()
|
|
|
|
usrPath := []string{"users", uid}
|
|
return m.bolt.SetValue(usrPath, "password", string(cryptPw))
|
|
}
|
|
|
|
// Is the uid and pw given valid?
|
|
func (m *model) checkCredentials(uid, pw string) error {
|
|
var err error
|
|
if err = m.openDB(); err != nil {
|
|
return err
|
|
}
|
|
defer m.closeDB()
|
|
|
|
var uPw string
|
|
usrPath := []string{"users", uid}
|
|
if uPw, err = m.bolt.GetValue(usrPath, "password"); err != nil {
|
|
return err
|
|
}
|
|
return bcrypt.CompareHashAndPassword([]byte(uPw), []byte(pw))
|
|
}
|
|
|
|
func (m *model) hasAdminUser() bool {
|
|
users := m.GetAllUsers()
|
|
for i := range users {
|
|
if users[i].IsAdmin {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|