package httpx import ( "context" "database/sql" "git.soup.land/soup/shelves/internal/auth" "log" "net/http" "time" ) type LogWrapper struct { statusCode *int http.ResponseWriter } func (w LogWrapper) WriteHeader(statusCode int) { *w.statusCode = statusCode w.ResponseWriter.WriteHeader(statusCode) } func Log(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { statusCode := 200 wrapper := LogWrapper{statusCode: &statusCode, ResponseWriter: w} start := time.Now() next.ServeHTTP(wrapper, r) log.Println(r.Method, r.URL.Path, statusCode, time.Since(start)) }) } func queryNeedsOwnerSetup(db *sql.DB) (bool, error) { count := 0 err := db.QueryRow("select count(*) from owner_settings").Scan(&count) if err != nil { return false, err } return count != 1, nil } func sessionInfo(db *sql.DB, r *http.Request) (auth.SessionInfo, error) { cookie, err := r.Cookie("SHELVES_OWNER_SESSION_ID") if err == http.ErrNoCookie { return auth.SessionInfo{}, nil } if err != nil { return auth.SessionInfo{}, err } return auth.SessionCheck(db, cookie.Value) } type Ctx struct { DB *sql.DB SessionInfo auth.SessionInfo NeedsOwnerSetup bool } func GetCtx(r *http.Request) Ctx { ctx := r.Context() return ctx.Value("__ctx").(Ctx) } func WithCtx(db *sql.DB, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { needsOwnerSetup, err := queryNeedsOwnerSetup(db) if err != nil { log.Printf("Error while querying owner_settings: %v\n", err) } ctx := r.Context() session, err := sessionInfo(db, r) if err != nil { log.Printf("Error while querying session info: %v\n", err) } ctx = context.WithValue(ctx, "__ctx", Ctx{ DB: db, SessionInfo: session, NeedsOwnerSetup: needsOwnerSetup, }) r = r.WithContext(ctx) next.ServeHTTP(w, r) }) }