rename go packages

This commit is contained in:
1e99 2025-05-21 17:15:55 +02:00
parent a48e22ba5f
commit fc04b6c9cd
9 changed files with 133 additions and 133 deletions

28
main.go
View file

@ -10,15 +10,15 @@ import (
"strconv"
"time"
"git.1e99.eu/1e99/passed/routes"
"git.1e99.eu/1e99/passed/storage"
"git.1e99.eu/1e99/passed/password"
"git.1e99.eu/1e99/passed/route"
)
//go:embed static/*
var embedFS embed.FS
func run() error {
store, err := newStore()
storage, err := newStorage()
if err != nil {
return err
}
@ -39,12 +39,12 @@ func run() error {
handler := http.Handler(mux)
mux.Handle("GET /", http.FileServerFS(staticFS))
mux.Handle("POST /api/password", routes.CreatePassword(store, maxPasswordLength))
mux.Handle("GET /api/password/{id}", routes.GetPassword(store))
mux.Handle("HEAD /api/password/{id}", routes.HasPassword(store))
mux.Handle("POST /api/password", route.CreatePassword(storage, maxPasswordLength))
mux.Handle("GET /api/password/{id}", route.GetPassword(storage))
mux.Handle("HEAD /api/password/{id}", route.HasPassword(storage))
if logRequests {
handler = routes.Logger(handler)
handler = route.Logger(handler)
}
log.Printf("Listening on %s.", address)
@ -76,15 +76,15 @@ func newStaticFS() (sfs fs.FS, err error) {
}
}
func newStore() (store storage.Store, err error) {
var storeType string
func newStorage() (storage password.Storage, err error) {
var storageType string
var clearInterval int
env("PASSED_STORE_TYPE", &storeType, "ram")
env("PASSED_STORE_TYPE", &storageType, "ram")
env("PASSED_STORE_CLEAR_INTERVAL", &clearInterval, "30")
switch storeType {
switch storageType {
case "ram":
store = storage.NewRamStore()
storage = password.NewRamStorage()
case "dir", "directory":
var path string
env("PASSED_STORE_DIR_PATH", &path, "passwords")
@ -94,7 +94,7 @@ func newStore() (store storage.Store, err error) {
return
}
store = storage.NewDirStore(path)
storage = password.NewDirStorage(path)
default:
err = errors.New("unknown storage type")
return
@ -105,7 +105,7 @@ func newStore() (store storage.Store, err error) {
for {
<-ticker
err := store.ClearExpired()
err := storage.ClearExpired()
if err != nil {
log.Printf("Failed to clear expired passwords: %s", err)
continue

View file

@ -1,4 +1,4 @@
package storage
package password
import (
"encoding/gob"
@ -7,12 +7,12 @@ import (
"time"
)
func NewDirStore(path string) Store {
store := &dir{
func NewDirStorage(path string) Storage {
storage := &dir{
path: path,
}
return store
return storage
}
type dir struct {
@ -24,10 +24,10 @@ type dirEntry struct {
ExpiresAt time.Time
}
func (store *dir) Create(password []byte, expiresAt time.Time) (string, error) {
func (s *dir) Create(password []byte, expiresAt time.Time) (string, error) {
for range 1000 {
id := generateId(24)
path := store.getPath(id)
path := s.getPath(id)
file, err := os.OpenFile(
path,
@ -59,8 +59,8 @@ func (store *dir) Create(password []byte, expiresAt time.Time) (string, error) {
return "", ErrFull
}
func (store *dir) Get(id string) ([]byte, error) {
entry, err := store.getEntry(id)
func (s *dir) Get(id string) ([]byte, error) {
entry, err := s.getEntry(id)
switch {
case os.IsNotExist(err):
return nil, ErrNotFound
@ -71,8 +71,8 @@ func (store *dir) Get(id string) ([]byte, error) {
return entry.Password, nil
}
func (store *dir) Delete(id string) error {
path := store.getPath(id)
func (s *dir) Delete(id string) error {
path := s.getPath(id)
err := os.Remove(path)
if err != nil {
return nil
@ -81,23 +81,23 @@ func (store *dir) Delete(id string) error {
return nil
}
func (store *dir) ClearExpired() error {
func (s *dir) ClearExpired() error {
now := time.Now()
entries, err := os.ReadDir(store.path)
entries, err := os.ReadDir(s.path)
if err != nil {
return err
}
for _, file := range entries {
id := file.Name()
entry, err := store.getEntry(id)
entry, err := s.getEntry(id)
if err != nil {
return err
}
if now.After(entry.ExpiresAt) {
err = store.Delete(id)
err = s.Delete(id)
if err != nil {
return err
}
@ -107,8 +107,8 @@ func (store *dir) ClearExpired() error {
return nil
}
func (store *dir) getEntry(id string) (dirEntry, error) {
path := store.getPath(id)
func (s *dir) getEntry(id string) (dirEntry, error) {
path := s.getPath(id)
file, err := os.OpenFile(
path,
os.O_RDONLY,
@ -129,6 +129,6 @@ func (store *dir) getEntry(id string) (dirEntry, error) {
return entry, nil
}
func (store *dir) getPath(id string) string {
return path.Join(store.path, id)
func (s *dir) getPath(id string) string {
return path.Join(s.path, id)
}

81
password/ram.go Normal file
View file

@ -0,0 +1,81 @@
package password
import (
"sync"
"time"
)
func NewRamStorage() Storage {
storage := &ram{
passwords: make(map[string]ramEntry),
lock: sync.Mutex{},
}
return storage
}
type ram struct {
passwords map[string]ramEntry
lock sync.Mutex
}
type ramEntry struct {
Password []byte
ExpiresAt time.Time
}
func (s *ram) Create(password []byte, expiresAt time.Time) (string, error) {
s.lock.Lock()
defer s.lock.Unlock()
for range 1000 {
id := generateId(24)
_, found := s.passwords[id]
if found {
continue
}
s.passwords[id] = ramEntry{
Password: password,
ExpiresAt: expiresAt,
}
return id, nil
}
return "", ErrFull
}
func (s *ram) Get(id string) ([]byte, error) {
s.lock.Lock()
defer s.lock.Unlock()
password, found := s.passwords[id]
if !found {
return nil, ErrNotFound
}
return password.Password, nil
}
func (s *ram) Delete(id string) error {
delete(s.passwords, id)
return nil
}
func (s *ram) ClearExpired() error {
s.lock.Lock()
defer s.lock.Unlock()
time := time.Now()
for id, password := range s.passwords {
if time.After(password.ExpiresAt) {
err := s.Delete(id)
if err != nil {
return err
}
}
}
return nil
}

View file

@ -1,4 +1,4 @@
package storage
package password
import (
"errors"
@ -11,7 +11,7 @@ var (
ErrFull = errors.New("storage is filled")
)
type Store interface {
type Storage interface {
Create(password []byte, expiresAt time.Time) (string, error)
Get(id string) ([]byte, error)
Delete(id string) error

View file

@ -1,14 +1,14 @@
package routes
package route
import (
"encoding/json"
"net/http"
"time"
"git.1e99.eu/1e99/passed/storage"
"git.1e99.eu/1e99/passed/password"
)
func CreatePassword(store storage.Store, maxLength int) http.HandlerFunc {
func CreatePassword(storage password.Storage, maxLength int) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
var reqBody struct {
// Go automatically decodes byte arrays using Base64
@ -37,12 +37,12 @@ func CreatePassword(store storage.Store, maxLength int) http.HandlerFunc {
return
}
id, err := store.Create(
id, err := storage.Create(
reqBody.Password,
time.Now().Add(expiresIn),
)
switch {
case err == storage.ErrFull:
case err == password.ErrFull:
http.Error(res, "Insufficient storage", http.StatusInsufficientStorage)
return
case err != nil:

View file

@ -1,18 +1,18 @@
package routes
package route
import (
"encoding/json"
"net/http"
"git.1e99.eu/1e99/passed/storage"
"git.1e99.eu/1e99/passed/password"
)
func GetPassword(store storage.Store) http.HandlerFunc {
func GetPassword(storage password.Storage) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
id := req.PathValue("id")
password, err := store.Get(id)
passwd, err := storage.Get(id)
switch {
case err == storage.ErrNotFound:
case err == password.ErrNotFound:
http.Error(res, "Password not found", http.StatusNotFound)
return
case err != nil:
@ -20,7 +20,7 @@ func GetPassword(store storage.Store) http.HandlerFunc {
return
}
err = store.Delete(id)
err = storage.Delete(id)
if err != nil {
http.Error(res, "", http.StatusInternalServerError)
return
@ -30,7 +30,7 @@ func GetPassword(store storage.Store) http.HandlerFunc {
// Go automatically encodes byte arrays using Base64
Password []byte `json:"password"`
}{
Password: password,
Password: passwd,
}
err = json.NewEncoder(res).Encode(&resBody)
if err != nil {

View file

@ -1,17 +1,17 @@
package routes
package route
import (
"net/http"
"git.1e99.eu/1e99/passed/storage"
"git.1e99.eu/1e99/passed/password"
)
func HasPassword(store storage.Store) http.HandlerFunc {
func HasPassword(storage password.Storage) http.HandlerFunc {
return func(res http.ResponseWriter, req *http.Request) {
id := req.PathValue("id")
_, err := store.Get(id)
_, err := storage.Get(id)
switch {
case err == storage.ErrNotFound:
case err == password.ErrNotFound:
http.Error(res, "", http.StatusNotFound)
return
case err != nil:

View file

@ -1,4 +1,4 @@
package routes
package route
import (
"log"

View file

@ -1,81 +0,0 @@
package storage
import (
"sync"
"time"
)
func NewRamStore() Store {
store := &ram{
passwords: make(map[string]ramEntry),
lock: sync.Mutex{},
}
return store
}
type ram struct {
passwords map[string]ramEntry
lock sync.Mutex
}
type ramEntry struct {
Password []byte
ExpiresAt time.Time
}
func (store *ram) Create(password []byte, expiresAt time.Time) (string, error) {
store.lock.Lock()
defer store.lock.Unlock()
for range 1000 {
id := generateId(24)
_, found := store.passwords[id]
if found {
continue
}
store.passwords[id] = ramEntry{
Password: password,
ExpiresAt: expiresAt,
}
return id, nil
}
return "", ErrFull
}
func (store *ram) Get(id string) ([]byte, error) {
store.lock.Lock()
defer store.lock.Unlock()
password, found := store.passwords[id]
if !found {
return nil, ErrNotFound
}
return password.Password, nil
}
func (store *ram) Delete(id string) error {
delete(store.passwords, id)
return 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) {
err := store.Delete(id)
if err != nil {
return err
}
}
}
return nil
}