ministream/server/users.go
2023-11-30 19:32:38 +01:00

101 lines
1.6 KiB
Go

package server
import (
"encoding/json"
"fmt"
"io"
"os"
"golang.org/x/crypto/bcrypt"
)
type User struct {
Username string `json:"username"`
HashedPassword []byte `json:"hashed_password"`
IsAdmin bool `json:"is_admin"`
}
func (u *User) SetPassword(password string) error {
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
if err != nil {
return err
}
u.HashedPassword = hash
return nil
}
func (u *User) VerifyPassword(password string) error {
return bcrypt.CompareHashAndPassword([]byte(u.HashedPassword), []byte(password))
}
type UserStore struct {
users map[string]*User
}
func NewUserStore() *UserStore {
return &UserStore{
users: make(map[string]*User),
}
}
var ErrNoSuchUser = fmt.Errorf("no such user")
func (s *UserStore) Put(u *User) error {
s.users[u.Username] = u
return nil
}
func (s *UserStore) Get(username string) (*User, error) {
u, ok := s.users[username]
if !ok {
return nil, ErrNoSuchUser
}
return u, nil
}
func (s *UserStore) ToWriter(w io.Writer) error {
enc := json.NewEncoder(w)
if err := enc.Encode(&s.users); err != nil {
return err
}
return nil
}
func (s *UserStore) ToFile(path string) error {
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
return s.ToWriter(f)
}
func StoreFromReader(r io.Reader) (*UserStore, error) {
dec := json.NewDecoder(r)
s := &UserStore{}
if err := dec.Decode(&s.users); err != nil {
return nil, err
}
return s, nil
}
func StoreFromFile(path string) (*UserStore, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
}
defer f.Close()
return StoreFromReader(f)
}