rework environment variables
This commit is contained in:
parent
1599edb83c
commit
d6e016719a
3 changed files with 91 additions and 62 deletions
37
config/config.go
Normal file
37
config/config.go
Normal 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
91
main.go
|
@ -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() {
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
Loading…
Reference in a new issue