package main import ( "encoding/gob" "flag" "fmt" "log" "net" "net/http" "os" "strconv" "github.com/gorilla/handlers" "github.com/gorilla/schema" "gosten/model" "gosten/templ" ) // flags var ( port uint64 host string ) func init() { flag.StringVar(&host, "h", "localhost", "address to listen on") flag.Uint64Var(&port, "p", 8080, "port to listen on") gob.Register(SessionData{}) } var Q *model.Queries var s *schema.Decoder func main() { flag.Parse() db := openDB("") if err := db.Ping(); err != nil { log.Fatal(err) } Q = model.New(db) s = schema.NewDecoder() mux := http.NewServeMux() mux.Handle("GET /login", loginPage()) mux.HandleFunc("POST /login", handleLogin) mux.Handle("GET /logout", handleLogout()) mux.Handle("/static/", http.StripPrefix("/static", http.FileServer(http.Dir("static")))) mux.Handle("/favicon.ico", http.NotFoundHandler()) handler := sessionHandler(mux) handler = handlers.CombinedLoggingHandler(os.Stderr, handler) handler = handlers.ProxyHeaders(handler) // the real content, needing authentification authMux := http.NewServeMux() mux.Handle("/", RequireAuth(authMux)) authMux.Handle("GET /{$}", indexPage()) address := net.JoinHostPort(host, strconv.FormatUint(port, 10)) log.Fatal(http.ListenAndServe(address, handler)) } type User struct { Name string `form:"options=required"` Password string `form:"type=password;options=required"` RememberMe bool `form:"type=checkbox;value=y;options=checked"` Errors []error `form:"-"` } type fieldError struct { Field string Issue string } func (fe fieldError) Error() string { return fmt.Sprintf("%s: %v", fe.Field, fe.Issue) } func (fe fieldError) FieldError() (field, err string) { return fe.Field, fe.Issue } func showTemplate(w http.ResponseWriter, tpl string, data any) { if err := templ.Lookup(tpl).Execute(w, data); err != nil { log.Panicf("Executing '%s' with %+v: %v", tpl, data, err) } } func parseForm[T any](r *http.Request, data *T) { if err := r.ParseForm(); err != nil { log.Panic("Parsing form: ", err) } if err := s.Decode(data, r.PostForm); err != nil { log.Panic("Decoding form: ", err) } } func indexPage() http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { uid := userId(r) u, _ := Q.GetUserById(r.Context(), uid) showTemplate(w, "index", u.Name) } }