package handlers import ( "encoding/gob" "fmt" "go-udemy-web-1/internal/config" "go-udemy-web-1/internal/models" "go-udemy-web-1/internal/render" "html/template" "log" "net/http" "os" "path/filepath" "time" "github.com/alexedwards/scs/v2" "github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5/middleware" "github.com/justinas/nosurf" ) var functions = template.FuncMap{} var ( app config.AppConfig session *scs.SessionManager ) func getRoutes() http.Handler { gob.Register(models.Reservation{}) // change this to true when in production app.InProduction = false session = scs.New() session.Lifetime = 24 * time.Hour session.Cookie.Persist = true session.Cookie.SameSite = http.SameSiteLaxMode session.Cookie.Secure = app.InProduction app.Session = session tc, err := CreateTestTemplateCache() if err != nil { log.Fatalf("cannot create template cache: %s", err) } app.TemplateCahce = tc app.UseCache = true // Not to use ./templates infoLog := log.New(os.Stdout, "INFO\t", log.Ldate|log.Ltime) app.InfoLog = infoLog errorLog := log.New(os.Stdout, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile) app.ErrorLog = errorLog repo := NewRepo(&app) NewHandlers(repo) render.NewRenderer(&app) mux := chi.NewMux() mux.Use(middleware.Recoverer) // mux.Use(NoSurf) // No need to test mux.Use(SessionLoad) mux.Get("/", Repo.Home) mux.Get("/about", Repo.About) mux.Get("/contact", Repo.Contact) mux.Get("/generals-quarters", Repo.Generals) mux.Get("/majors-suite", Repo.Majors) mux.Get("/availability", Repo.Availability) mux.Post("/availability", Repo.PostAvailability) mux.Post("/availability-json", Repo.AvailabilityJSON) mux.Get("/make-reservation", Repo.MakeReservation) mux.Post("/make-reservation", Repo.PostMakeReservation) mux.Get("/reservation-summary", Repo.ReservationSummary) fileServer := http.FileServer(http.Dir("./static/")) mux.Handle("/static/*", http.StripPrefix("/static", fileServer)) return mux } // WriteToConsole writes a log when user hits a page func WriteToConsole(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { fmt.Printf("Hit the page %s\n", r.URL.String()) next.ServeHTTP(w, r) }) } // NoSurf adds CSRF protection to all POST requests func NoSurf(next http.Handler) http.Handler { csrfHandler := nosurf.New(next) csrfHandler.SetBaseCookie(http.Cookie{ HttpOnly: true, Path: "/", Secure: app.InProduction, SameSite: http.SameSiteLaxMode, }) return csrfHandler } // SessionLoad loads and saves the session on every request func SessionLoad(next http.Handler) http.Handler { return session.LoadAndSave(next) } var pathToTemplates = "../../templates" func CreateTestTemplateCache() (map[string]*template.Template, error) { myCache := map[string]*template.Template{} // get all of the files named *.page.tmpl from templates pages, err := filepath.Glob(fmt.Sprintf("%s/*.page.tmpl", pathToTemplates)) if err != nil { return myCache, err } // range through all files ending with *page.tmpl for _, page := range pages { name := filepath.Base(page) ts, err := template.New(name).Funcs(functions).ParseFiles(page) if err != nil { return myCache, err } matches, err := filepath.Glob(fmt.Sprintf("%s/*.layout.tmpl", pathToTemplates)) if err != nil { return myCache, err } if len(matches) > 0 { ts, err = ts.ParseGlob(fmt.Sprintf("%s/*.layout.tmpl", pathToTemplates)) if err != nil { return myCache, err } } myCache[name] = ts } return myCache, nil }