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) }