package storage import ( "errors" "log" "math/rand/v2" "os" "strings" "time" ) var ( ErrNotFound = errors.New("password not found") ErrFull = errors.New("storage is filled") ) type entry struct { Password []byte ExpiresAt time.Time } type Store interface { Create(password []byte, expiresAt time.Time) (string, error) Get(id string) ([]byte, error) Delete(id string) error ClearExpired() error } func NewStore() (Store, error) { storeType := os.Getenv("PASSED_STORE_TYPE") storeType = strings.ToLower(storeType) switch storeType { case "ram": return NewRamStore(), nil case "dir": path := os.Getenv("PASSED_STORE_DIR_PATH") if path == "" { log.Printf("No PASSED_STORE_DIR_PATH provided, defaulting to \"passwords\".") path = "passwords" } return NewDirStore(path), nil default: log.Printf("No PASSED_STORE_TYPE provided, defaulting to memory store.") return NewRamStore(), nil } } func 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) }