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