88 lines
1.5 KiB
Go
88 lines
1.5 KiB
Go
package auth
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"io/fs"
|
|
"os"
|
|
"sync"
|
|
)
|
|
|
|
type Store struct {
|
|
file string
|
|
users map[int64]bool
|
|
mu sync.RWMutex
|
|
}
|
|
|
|
func New(file string) (*Store, error) {
|
|
users, err := loadUsers(file)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &Store{
|
|
file: file,
|
|
users: users,
|
|
}, nil
|
|
}
|
|
func (s *Store) IsAllowed(userID int64) bool {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
return s.users[userID]
|
|
}
|
|
func (s *Store) IsEmpty() bool {
|
|
s.mu.RLock()
|
|
defer s.mu.RUnlock()
|
|
return len(s.users) == 0
|
|
}
|
|
func (s *Store) FirstUser(userID int64) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.users[userID] = true
|
|
return s.save()
|
|
}
|
|
func (s *Store) Add(userID int64) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
s.users[userID] = true
|
|
return s.save()
|
|
}
|
|
func (s *Store) Remove(userID int64) error {
|
|
s.mu.Lock()
|
|
defer s.mu.Unlock()
|
|
delete(s.users, userID)
|
|
return s.save()
|
|
}
|
|
func (s *Store) save() error {
|
|
data, err := json.MarshalIndent(s.users, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
tmpFile := s.file + ".tmp"
|
|
if err := os.WriteFile(tmpFile, data, 0644); err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.Rename(tmpFile, s.file)
|
|
}
|
|
func loadUsers(file string) (map[int64]bool, error) {
|
|
data, err := os.ReadFile(file)
|
|
if err != nil {
|
|
if errors.Is(err, fs.ErrNotExist) {
|
|
return make(map[int64]bool), nil
|
|
}
|
|
return nil, err
|
|
}
|
|
|
|
users := make(map[int64]bool)
|
|
if len(data) == 0 {
|
|
return users, nil
|
|
}
|
|
|
|
if err := json.Unmarshal(data, &users); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return users, nil
|
|
}
|