passed/storage/ram.go
2024-10-30 00:08:11 +01:00

90 lines
1.4 KiB
Go

package storage
import (
"math/rand/v2"
"sync"
"time"
)
func NewRamStore() Store {
store := &ram{
passwords: make(map[string]entry),
lock: sync.Mutex{},
}
go func() {
ticker := time.Tick(25 * time.Second)
for {
store.clearExpired()
<-ticker
}
}()
return store
}
type ram struct {
passwords map[string]entry
lock sync.Mutex
}
func (store *ram) CreatePassword(password []byte, expiresAt time.Time) (string, error) {
store.lock.Lock()
defer store.lock.Unlock()
for range 1000 {
id := store.generateId(24)
_, found := store.passwords[id]
if found {
continue
}
store.passwords[id] = entry{
password: password,
expiresAt: expiresAt,
}
return id, nil
}
return "", ErrFull
}
func (store *ram) GetPassword(id string) ([]byte, error) {
store.lock.Lock()
defer store.lock.Unlock()
password, found := store.passwords[id]
if !found {
return nil, ErrNotFound
}
delete(store.passwords, id)
return password.password, nil
}
func (store *ram) clearExpired() error {
store.lock.Lock()
defer store.lock.Unlock()
time := time.Now()
for id, password := range store.passwords {
if time.After(password.expiresAt) {
delete(store.passwords, id)
}
}
return nil
}
func (store *ram) generateId(length int) string {
runes := []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
str := make([]rune, length)
for i := range str {
str[i] = runes[rand.IntN(len(runes))]
}
return string(str)
}