package api import ( "context" "fmt" "net/http" "time" "git.freecumextremist.com/grumbulon/pomme/internal" "git.freecumextremist.com/grumbulon/pomme/internal/db" "github.com/go-chi/chi/v5" "github.com/go-chi/jwtauth/v5" "github.com/go-chi/render" ) type key int const ( keyPrincipalContextID key = iota ) // SetDBMiddleware is the http Handler func for the GORM middleware with context. func SetDBMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { db := db.InitDb() timeoutContext, cancelContext := context.WithTimeout(context.Background(), time.Second) ctx := context.WithValue(r.Context(), keyPrincipalContextID, db.WithContext(timeoutContext)) defer cancelContext() next.ServeHTTP(w, r.WithContext(ctx)) }) } func basicAuthFailed(w http.ResponseWriter, realm string) { w.Header().Add("WWW-Authenticate", fmt.Sprintf(`Basic realm="%s"`, realm)) w.WriteHeader(http.StatusUnauthorized) } // API subroute handler. func API() http.Handler { api := chi.NewRouter() // Protected routes api.Group(func(api chi.Router) { api.Use(jwtauth.Verifier(tokenAuth)) api.Use(jwtauth.Authenticator) api.Post("/check", Ingest) api.Get("/private", AuthTest) }) // Open routes api.Group(func(api chi.Router) { api.Use(SetDBMiddleware) api.With(SetDBMiddleware).Post("/create", NewUser) api.With(SetDBMiddleware).Post("/login", Login) api.Post("/logout", Logout) }) return api } // Ingest is a function to ingest Zonefiles. func Ingest(w http.ResponseWriter, r *http.Request) { _ = &internal.ZoneRequest{} // todo write to database, maybe? // todo -- add functions to apply to master zonefile if above check is OK. render.Status(r, http.StatusAccepted) } // AuthTest is for testing protected routes. func AuthTest(w http.ResponseWriter, r *http.Request) { _, claims, _ := jwtauth.FromContext(r.Context()) _, err := w.Write([]byte(fmt.Sprintf("protected area. hi %v", claims["username"]))) if err != nil { http.Error(w, "internal server error", http.StatusInternalServerError) return } }