Repo with a simple http server with auth to serve my email.
Author: blmayer (bleemayer@gmail.com)
Date: Wed Nov 15 10:10:36 2023 -0300
Parent: e0ebb54
Fixed auth
diff --git a/Makefile b/Makefile index e8310ec..97bfad2 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ deploy: $(wildcard cmd/web/*.go) GOARCH=arm GOARM=6 go build $^ - scp main zero:dovel-web + scp -O main zero:dovel-web ssh zero "mv dovel-web .local/bin" deploy-certs: fullchain.pem privkey.pem
diff --git a/cmd/web/main.go b/cmd/web/main.go index 91bb1c8..819a891 100644 --- a/cmd/web/main.go +++ b/cmd/web/main.go @@ -2,12 +2,10 @@ package main import ( "encoding/json" + "log/slog" "net/http" "os" "path" - "log/slog" - - "git.derelict.garden/bryon/vault" ) type Config struct { @@ -29,13 +27,20 @@ func (u user) Pass() string { } var ( - v vault.Vault[user] + v *vault cfg Config ) func private(w http.ResponseWriter, r *http.Request) { - name, pass, ok := r.BasicAuth() - if !ok || name == "" || pass == "" { + name, pass, _ := r.BasicAuth() + if name == "" || pass == "" { + w.Header().Add("WWW-Authenticate", "Basic") + w.WriteHeader(http.StatusUnauthorized) + return + } + slog.Debug("authenticating request", "user", name, "pass", pass) + if !v.Validate(name, pass) { + slog.Debug("authentication failed") w.Header().Add("WWW-Authenticate", "Basic") w.WriteHeader(http.StatusUnauthorized) return @@ -49,6 +54,14 @@ func private(w http.ResponseWriter, r *http.Request) { } func main() { + if os.Getenv("DEBUG") != "" { + slog.SetDefault( + slog.New(slog.NewTextHandler( + os.Stdout, &slog.HandlerOptions{ + Level: slog.LevelDebug, + })), + ) + } configPath, err := os.UserConfigDir() if err != nil { println(err, "using ~/.config/dovel/web.json") @@ -61,9 +74,9 @@ func main() { panic("open config: " + err.Error()) } json.NewDecoder(configFile).Decode(&cfg) - slog.Info("loaded config", cfg) + slog.Info("loaded", "config", cfg) - v, err = vault.NewJSONPlainTextVault[user](path.Join(configPath, "users.json")) + v, err = NewVault(path.Join(configPath, "users.json")) if err != nil { panic("new vault: " + err.Error()) }
diff --git a/cmd/web/vault.go b/cmd/web/vault.go new file mode 100644 index 0000000..5e89c9a --- /dev/null +++ b/cmd/web/vault.go @@ -0,0 +1,56 @@ +package main + +import ( + "crypto/sha256" + "encoding/json" + "fmt" + "log/slog" + "os" + "sync" +) + +type vault struct { + mu sync.Mutex + path string + Users []user +} + +func NewVault(path string) (*vault, error) { + s := &vault{Users: []user{}, path: path, mu: sync.Mutex{}} + + file, err := os.Open(path) + if err != nil { + return s, err + } + defer file.Close() + + err = json.NewDecoder(file).Decode(&s.Users) + if err != nil { + return s, err + } + slog.Debug("vault", "users", s.Users) + + return s, nil +} + +func (v *vault) GetUser(login string) user { + for _, u := range v.Users { + if u.Name == login { + return u + } + } + return user{} +} + +func (v *vault) Validate(login, pass string) bool { + user := v.GetUser(login) + if user.Name != "" { + shapass := fmt.Sprintf("%x", sha256.Sum256([]byte(pass))) + slog.Debug("vault", "sha256", shapass) + if user.Pass() == shapass { + return true + } + } + return false +} +