diff --git a/.air.toml b/.air.toml index 498951f..8e2e597 100644 --- a/.air.toml +++ b/.air.toml @@ -3,50 +3,50 @@ testdata_dir = "testdata" tmp_dir = "tmp" [build] - args_bin = [] - bin = "./tmp/main" - cmd = "go build -o ./tmp/main ." - delay = 1000 - exclude_dir = ["assets", "tmp", "vendor", "testdata"] - exclude_file = [] - exclude_regex = ["_test.go"] - exclude_unchanged = false - follow_symlink = false - full_bin = "" - include_dir = [] - include_ext = ["go", "tpl", "tmpl", "html"] - include_file = [] - kill_delay = "0s" - log = "build-errors.log" - poll = false - poll_interval = 0 - post_cmd = [] - pre_cmd = [] - rerun = false - rerun_delay = 500 - send_interrupt = false - stop_on_error = false +args_bin = [] +bin = "./tmp/main" +cmd = "go build -o ./tmp/main ./cmd/server/main.go" +delay = 1000 +exclude_dir = ["assets", "tmp", "vendor", "testdata"] +exclude_file = [] +exclude_regex = ["_test.go"] +exclude_unchanged = false +follow_symlink = false +full_bin = "" +include_dir = [] +include_ext = ["go", "tpl", "tmpl", "html"] +include_file = [] +kill_delay = "0s" +log = "build-errors.log" +poll = false +poll_interval = 0 +post_cmd = [] +pre_cmd = [] +rerun = false +rerun_delay = 500 +send_interrupt = false +stop_on_error = false [color] - app = "" - build = "yellow" - main = "magenta" - runner = "green" - watcher = "cyan" +app = "" +build = "yellow" +main = "magenta" +runner = "green" +watcher = "cyan" [log] - main_only = false - silent = false - time = false +main_only = false +silent = false +time = false [misc] - clean_on_exit = false +clean_on_exit = false [proxy] - app_port = 0 - enabled = false - proxy_port = 0 +app_port = 0 +enabled = false +proxy_port = 0 [screen] - clear_on_rebuild = false - keep_scroll = true +clear_on_rebuild = false +keep_scroll = true diff --git a/cmd/server/main.go b/cmd/server/main.go index 30c68c0..b120d7d 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -1,56 +1,17 @@ package main import ( - "html/template" "log" "net/http" - "github.com/rjnemo/auth/web" -) - -var ( - loggedIn = false - templates = template.Must(template.ParseFS(web.Templates, "templates/index.html", "templates/in.html", "templates/unauthorized.html")) + "github.com/rjnemo/auth/internal/server" ) func main() { - mux := http.NewServeMux() - - mux.HandleFunc("GET /", handleIndex) - mux.HandleFunc("GET /in", handleIn) - mux.HandleFunc("POST /login", handleLogin) + srv := server.New() log.Println("Starting server on http://localhost:8000") - if err := http.ListenAndServe(":8000", mux); err != nil { + if err := http.ListenAndServe(":8000", srv.Router()); err != nil { log.Fatalf("listen: %v", err) } } - -func handleIndex(w http.ResponseWriter, r *http.Request) { - err := templates.ExecuteTemplate(w, "index.html", nil) - if err != nil { - http.Error(w, "template render failed", http.StatusInternalServerError) - } -} - -func handleIn(w http.ResponseWriter, r *http.Request) { - if !loggedIn { - w.WriteHeader(http.StatusUnauthorized) - err := templates.ExecuteTemplate(w, "unauthorized.html", nil) - if err != nil { - http.Error(w, "template render failed", http.StatusInternalServerError) - } - return - } - - err := templates.ExecuteTemplate(w, "in.html", nil) - if err != nil { - http.Error(w, "template render failed", http.StatusInternalServerError) - } -} - -func handleLogin(w http.ResponseWriter, r *http.Request) { - log.Println("Login request received") - loggedIn = true - http.Redirect(w, r, "/in", http.StatusSeeOther) -} diff --git a/go.mod b/go.mod index ce9e126..aacce5d 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/rjnemo/auth go 1.25.1 + +require github.com/go-chi/chi/v5 v5.2.3 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..5bd7be3 --- /dev/null +++ b/go.sum @@ -0,0 +1,2 @@ +github.com/go-chi/chi/v5 v5.2.3 h1:WQIt9uxdsAbgIYgid+BpYc+liqQZGMHRaUwp0JUcvdE= +github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops= diff --git a/internal/server/handler_auth.go b/internal/server/handler_auth.go new file mode 100644 index 0000000..a6af4bc --- /dev/null +++ b/internal/server/handler_auth.go @@ -0,0 +1,14 @@ +package server + +import ( + "log" + "net/http" +) + +func (s *Server) loginHandler() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + log.Println("Login request received") + s.loggedIn = true + http.Redirect(w, r, "/in", http.StatusSeeOther) + } +} diff --git a/internal/server/handler_dashboard.go b/internal/server/handler_dashboard.go new file mode 100644 index 0000000..0d82359 --- /dev/null +++ b/internal/server/handler_dashboard.go @@ -0,0 +1,24 @@ +package server + +import ( + "log" + "net/http" +) + +func (s *Server) dashboardHandler() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if !s.loggedIn { + w.WriteHeader(http.StatusUnauthorized) + if err := s.templates.ExecuteTemplate(w, "unauthorized.html", nil); err != nil { + log.Printf("render unauthorized: %v", err) + http.Error(w, "template render failed", http.StatusInternalServerError) + } + return + } + + if err := s.templates.ExecuteTemplate(w, "in.html", nil); err != nil { + log.Printf("render dashboard: %v", err) + http.Error(w, "template render failed", http.StatusInternalServerError) + } + } +} diff --git a/internal/server/handler_public.go b/internal/server/handler_public.go new file mode 100644 index 0000000..9635740 --- /dev/null +++ b/internal/server/handler_public.go @@ -0,0 +1,15 @@ +package server + +import ( + "log" + "net/http" +) + +func (s *Server) indexHandler() http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + if err := s.templates.ExecuteTemplate(w, "index.html", nil); err != nil { + log.Printf("render index: %v", err) + http.Error(w, "template render failed", http.StatusInternalServerError) + } + } +} diff --git a/internal/server/routes.go b/internal/server/routes.go new file mode 100644 index 0000000..65a6122 --- /dev/null +++ b/internal/server/routes.go @@ -0,0 +1,9 @@ +package server + +import "github.com/go-chi/chi/v5" + +func (s *Server) registerRoutes(r chi.Router) { + r.Get("/", s.indexHandler()) + r.Get("/in", s.dashboardHandler()) + r.Post("/login", s.loginHandler()) +} diff --git a/internal/server/server.go b/internal/server/server.go new file mode 100644 index 0000000..bba204c --- /dev/null +++ b/internal/server/server.go @@ -0,0 +1,37 @@ +package server + +import ( + "html/template" + "net/http" + + "github.com/go-chi/chi/v5" + + "github.com/rjnemo/auth/web" +) + +// Server holds HTTP dependencies for the application. +type Server struct { + templates *template.Template + loggedIn bool +} + +// New constructs a Server with parsed templates and default state. +func New() *Server { + tmpl := template.Must(template.ParseFS( + web.Templates, + "templates/index.html", + "templates/in.html", + "templates/unauthorized.html", + )) + + return &Server{ + templates: tmpl, + } +} + +// Router returns the configured HTTP router. +func (s *Server) Router() http.Handler { + r := chi.NewRouter() + s.registerRoutes(r) + return r +}