package middleware import ( "crypto/sha256" "crypto/subtle" "net/http" "nonsense-time/db" ) func BasicAuth(next http.Handler, authProvider db.AuthProvider) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { username, password, ok := r.BasicAuth() if !ok || !authProvider.UserExists(username) { w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`) http.Error(w, "Unauthorized", http.StatusUnauthorized) return } salt := authProvider.Salt(username) input := []byte(password) input = append(input, salt[:]...) passSaltHash := sha256.Sum256(input) expectedSaltHash := authProvider.SaltedHash(username) if subtle.ConstantTimeCompare(expectedSaltHash[:], passSaltHash[:]) != 1 { w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`) http.Error(w, "Unauthorized", http.StatusUnauthorized) return } next.ServeHTTP(w, r) }) }