rework environment variables

This commit is contained in:
1e99 2024-11-08 16:00:17 +01:00
parent 1599edb83c
commit d6e016719a
3 changed files with 91 additions and 62 deletions

37
config/config.go Normal file
View file

@ -0,0 +1,37 @@
package config
import (
"log"
"os"
"strconv"
)
func Env(name string, out any, def string) {
raw := os.Getenv(name)
if raw == "" {
raw = def
log.Printf("No \"%s\" provided, defaulting to \"%s\".", name, def)
}
switch value := out.(type) {
case *int:
i, err := strconv.ParseInt(raw, 10, 64)
if err != nil {
log.Printf("\"%s\" is not a number.", name)
return
}
*value = int(i)
case *bool:
switch raw {
case "true", "TRUE", "1":
*value = true
case "false", "FALSE", "0":
*value = false
}
case *string:
*value = raw
}
}

91
main.go
View file

@ -3,12 +3,12 @@ package main
import (
"embed"
"encoding/base64"
"errors"
"log"
"net/http"
"os"
"strconv"
"time"
"git.1e99.eu/1e99/passed/config"
"git.1e99.eu/1e99/passed/middlewares"
"git.1e99.eu/1e99/passed/routes"
"git.1e99.eu/1e99/passed/storage"
@ -18,21 +18,63 @@ import (
var embedFS embed.FS
func run() error {
storage, err := storage.NewStore()
storage, err := newStore()
if err != nil {
return err
}
clearIntervalString := os.Getenv("STORE_CLEAR_EXPIRED_INTERVAL")
if clearIntervalString == "" {
log.Printf("No STORE_CLEAR_EXPIRED_INTERVAL provided, defaulting to 30 seconds.")
clearIntervalString = "30"
var address string
var logRequests bool
var maxPasswordLength int
config.Env("PASSED_ADDRESS", &address, ":3000")
config.Env("PASSED_LOG_REQUESTS", &logRequests, "true")
config.Env("PASSED_MAX_LENGTH", &maxPasswordLength, "12288")
mux := http.NewServeMux()
handler := http.Handler(mux)
mux.Handle("GET /", routes.ServeFiles(embedFS, "static"))
mux.Handle(
"POST /api/password",
middlewares.RateLimiter(
routes.CreatePassword(storage, maxPasswordLength, base64.StdEncoding),
1*time.Minute,
5,
),
)
mux.Handle("GET /api/password/{id}", routes.GetPassword(storage, base64.StdEncoding))
mux.Handle("HEAD /api/password/{id}", routes.HasPassword(storage))
if logRequests {
handler = middlewares.Logger(handler)
}
clearInterval, err := strconv.ParseInt(clearIntervalString, 10, 64)
log.Printf("Listening on %s.", address)
err = http.ListenAndServe(address, handler)
if err != nil {
log.Printf("STORE_CLEAR_EXPIRED_INTERVAL is not a number.")
clearInterval = 30
return err
}
return nil
}
func newStore() (store storage.Store, err error) {
var storeType string
var clearInterval int
config.Env("PASSED_STORE", &storeType, "ram")
config.Env("PASSED_STORE_CLEAR_INTERVAL", &clearInterval, "30")
switch storeType {
case "ram":
store = storage.NewRamStore()
case "dir", "directory":
var path string
config.Env("PASSED_STORE_DIR_PATH", &path, "passwords")
store = storage.NewDirStore(path)
default:
err = errors.New("unknown storage type")
return
}
go func() {
@ -40,7 +82,7 @@ func run() error {
for {
<-ticker
err := storage.ClearExpired()
err := store.ClearExpired()
if err != nil {
log.Printf("Failed to clear expired passwords: %s", err)
continue
@ -50,32 +92,7 @@ func run() error {
}
}()
mux := http.NewServeMux()
mux.Handle("GET /", routes.ServeFiles(embedFS, "static"))
mux.Handle(
"POST /api/password",
middlewares.RateLimiter(
routes.CreatePassword(storage, 12*1024, base64.StdEncoding),
1*time.Minute,
5,
),
)
mux.Handle("GET /api/password/{id}", routes.GetPassword(storage, base64.StdEncoding))
mux.Handle("HEAD /api/password/{id}", routes.HasPassword(storage))
address := os.Getenv("PASSED_ADDRESS")
if address == "" {
log.Printf("No PASSED_ADDRESS provided, defaulting to \":3000\"")
address = ":3000"
}
log.Printf("Listening on %s", address)
err = http.ListenAndServe(address, middlewares.Logger(mux))
if err != nil {
return err
}
return nil
return
}
func main() {

View file

@ -2,10 +2,7 @@ package storage
import (
"errors"
"log"
"math/rand/v2"
"os"
"strings"
"time"
)
@ -21,28 +18,6 @@ type Store interface {
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")