fix: fix routing and dependency injection
This commit is contained in:
parent
7b6f4f39c2
commit
ae26700e59
@ -1,12 +1,12 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
"git.markbailey.dev/cerbervs/ptpp/app/session"
|
||||
"git.markbailey.dev/cerbervs/ptpp/lib/logger"
|
||||
"net/http"
|
||||
|
||||
"git.markbailey.dev/cerbervs/ptpp/app/session"
|
||||
"git.markbailey.dev/cerbervs/ptpp/lib/logger"
|
||||
|
||||
"git.markbailey.dev/cerbervs/ptpp/lib/database"
|
||||
werror "git.markbailey.dev/cerbervs/ptpp/lib/error"
|
||||
)
|
||||
|
||||
type IController interface {
|
||||
@ -19,7 +19,7 @@ type IController interface {
|
||||
Post(w http.ResponseWriter, r *http.Request) error
|
||||
Patch(w http.ResponseWriter, r *http.Request) error
|
||||
Connect(w http.ResponseWriter, r *http.Request) error
|
||||
Init(session.IManager, database.IDB, logger.ILogger) error
|
||||
Init(session.IManager, database.IDB, logger.ILogger) IController
|
||||
}
|
||||
|
||||
type Controller struct {
|
||||
@ -28,8 +28,8 @@ type Controller struct {
|
||||
Logger logger.ILogger
|
||||
}
|
||||
|
||||
func (c Controller) Init(s session.IManager, d database.IDB, l logger.ILogger) error {
|
||||
return werror.Wrap(nil, "You must implement the init method in your extended controller")
|
||||
func (c Controller) Init(s session.IManager, d database.IDB, l logger.ILogger) IController {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Controller) Get(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
@ -39,6 +39,7 @@ func (c Controller) Get(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Controller) Head(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
if _, err := w.Write([]byte("not implemented")); err != nil {
|
||||
c.Logger.Error(c.Logger.Wrap(err, "Error writing response"))
|
||||
@ -46,6 +47,7 @@ func (c Controller) Head(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Controller) Options(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
if _, err := w.Write([]byte("not implemented")); err != nil {
|
||||
c.Logger.Error(c.Logger.Wrap(err, "Error writing response"))
|
||||
@ -53,6 +55,7 @@ func (c Controller) Options(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Controller) Trace(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
if _, err := w.Write([]byte("not implemented")); err != nil {
|
||||
c.Logger.Error(c.Logger.Wrap(err, "Error writing response"))
|
||||
@ -60,6 +63,7 @@ func (c Controller) Trace(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Controller) Put(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
if _, err := w.Write([]byte("not implemented")); err != nil {
|
||||
c.Logger.Error(c.Logger.Wrap(err, "Error writing response"))
|
||||
@ -67,6 +71,7 @@ func (c Controller) Put(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Controller) Delete(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
if _, err := w.Write([]byte("not implemented")); err != nil {
|
||||
c.Logger.Error(c.Logger.Wrap(err, "Error writing response"))
|
||||
@ -74,6 +79,7 @@ func (c Controller) Delete(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Controller) Post(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
if _, err := w.Write([]byte("not implemented")); err != nil {
|
||||
c.Logger.Error(c.Logger.Wrap(err, "Error writing response"))
|
||||
@ -81,6 +87,7 @@ func (c Controller) Post(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Controller) Patch(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
if _, err := w.Write([]byte("not implemented")); err != nil {
|
||||
c.Logger.Error(c.Logger.Wrap(err, "Error writing response"))
|
||||
@ -88,6 +95,7 @@ func (c Controller) Patch(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c Controller) Connect(w http.ResponseWriter, _ *http.Request) (_ error) {
|
||||
if _, err := w.Write([]byte("not implemented")); err != nil {
|
||||
c.Logger.Error(c.Logger.Wrap(err, "Error writing response"))
|
||||
|
@ -1,10 +1,12 @@
|
||||
package handler
|
||||
|
||||
import "net/http"
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
type Handler func(http.ResponseWriter, *http.Request) error
|
||||
type HandlerFunc func(http.ResponseWriter, *http.Request) error
|
||||
|
||||
func (fn Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
func (fn HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if err := fn(w, r); err != nil {
|
||||
w.Header().Set("HX-Retarget", "#layout_content")
|
||||
w.Header().Set("HX-Reswap", "innerHTML")
|
||||
|
@ -1,6 +1,8 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.markbailey.dev/cerbervs/ptpp/app/controller"
|
||||
"git.markbailey.dev/cerbervs/ptpp/app/handler"
|
||||
"git.markbailey.dev/cerbervs/ptpp/app/session"
|
||||
@ -9,7 +11,6 @@ import (
|
||||
"git.markbailey.dev/cerbervs/ptpp/lib/logger"
|
||||
"git.markbailey.dev/cerbervs/ptpp/lib/middleware"
|
||||
"git.markbailey.dev/cerbervs/ptpp/util"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
var sess session.IManager
|
||||
@ -26,21 +27,22 @@ type Route struct {
|
||||
|
||||
type Router struct {
|
||||
Mux *http.ServeMux
|
||||
BasePath string
|
||||
Routes []Route
|
||||
SubRouters *[]Router
|
||||
Middleware *[]middleware.Func
|
||||
BasePath string
|
||||
Routes []Route
|
||||
}
|
||||
|
||||
func (r Router) HandleAllRequestMethods(route Route) {
|
||||
r.Mux.Handle("GET "+r.BasePath+route.Path, handler.Handler(route.Controller.Get))
|
||||
r.Mux.Handle("OPTIONS "+r.BasePath+route.Path, handler.Handler(route.Controller.Options))
|
||||
r.Mux.Handle("TRACE "+r.BasePath+route.Path, handler.Handler(route.Controller.Trace))
|
||||
r.Mux.Handle("PUT "+r.BasePath+route.Path, handler.Handler(route.Controller.Put))
|
||||
r.Mux.Handle("DELETE "+r.BasePath+route.Path, handler.Handler(route.Controller.Delete))
|
||||
r.Mux.Handle("POST "+r.BasePath+route.Path, handler.Handler(route.Controller.Post))
|
||||
r.Mux.Handle("PATCH "+r.BasePath+route.Path, handler.Handler(route.Controller.Patch))
|
||||
r.Mux.Handle("CONNECT "+r.BasePath+route.Path, handler.Handler(route.Controller.Connect))
|
||||
c := route.Controller.Init(sess, database.ChooseDB(), logger.NewCompositeLogger())
|
||||
r.Mux.Handle("GET "+r.BasePath+route.Path, handler.HandlerFunc(c.Get))
|
||||
r.Mux.Handle("OPTIONS "+r.BasePath+route.Path, handler.HandlerFunc(c.Options))
|
||||
r.Mux.Handle("TRACE "+r.BasePath+route.Path, handler.HandlerFunc(c.Trace))
|
||||
r.Mux.Handle("PUT "+r.BasePath+route.Path, handler.HandlerFunc(c.Put))
|
||||
r.Mux.Handle("DELETE "+r.BasePath+route.Path, handler.HandlerFunc(c.Delete))
|
||||
r.Mux.Handle("POST "+r.BasePath+route.Path, handler.HandlerFunc(c.Post))
|
||||
r.Mux.Handle("PATCH "+r.BasePath+route.Path, handler.HandlerFunc(c.Patch))
|
||||
r.Mux.Handle("CONNECT "+r.BasePath+route.Path, handler.HandlerFunc(c.Connect))
|
||||
}
|
||||
|
||||
func (r Router) RegisterRoutes() http.Handler {
|
||||
@ -49,10 +51,6 @@ func (r Router) RegisterRoutes() http.Handler {
|
||||
}
|
||||
|
||||
for _, route := range r.Routes {
|
||||
if err := route.Controller.Init(sess, database.ChooseDB(), logger.NewCompositeLogger()); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
r.HandleAllRequestMethods(route)
|
||||
}
|
||||
|
||||
@ -108,6 +106,7 @@ func (r Router) GetRouteByName(name string) (string, error) {
|
||||
|
||||
return "", werror.Wrap(nil, "Route not found")
|
||||
}
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
|
||||
|
@ -11,7 +11,7 @@ var AppRouter = Router{
|
||||
Mux: http.NewServeMux(),
|
||||
BasePath: "/",
|
||||
Routes: []Route{
|
||||
{Controller: &shared.HomePageHandler{}, Path: "", Name: "app.index"},
|
||||
{Controller: &shared.HomePageController{}, Path: "", Name: "app.index"},
|
||||
{Controller: &shared.SignUpHandler{}, Path: "sign-up", Name: "app.user.sign_up"},
|
||||
{Controller: &shared.SignInHandler{}, Path: "sign-in", Name: "app.user.sign_in"},
|
||||
{Controller: &shared.SignOutHandler{}, Path: "sign-out", Name: "app.user.sign_out"},
|
||||
|
2
go.mod
2
go.mod
@ -1,6 +1,6 @@
|
||||
module git.markbailey.dev/cerbervs/ptpp
|
||||
|
||||
go 1.23.2
|
||||
go 1.23
|
||||
|
||||
require (
|
||||
github.com/a-h/templ v0.2.793
|
||||
|
@ -17,12 +17,12 @@ type IndexHandler struct {
|
||||
controller.Controller
|
||||
}
|
||||
|
||||
func (h IndexHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) error {
|
||||
func (h IndexHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) controller.IController {
|
||||
h.Logger = l
|
||||
h.Db = d
|
||||
h.Session = s
|
||||
|
||||
return nil
|
||||
return h
|
||||
}
|
||||
|
||||
func (h IndexHandler) Get(w http.ResponseWriter, r *http.Request) error {
|
||||
|
@ -13,19 +13,19 @@ import (
|
||||
"git.markbailey.dev/cerbervs/ptpp/view/homepage"
|
||||
)
|
||||
|
||||
type HomePageHandler struct {
|
||||
type HomePageController struct {
|
||||
controller.Controller
|
||||
}
|
||||
|
||||
func (h HomePageHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) error {
|
||||
h.Logger = l
|
||||
h.Db = d
|
||||
h.Session = s
|
||||
func (c HomePageController) Init(s session.IManager, d database.IDB, l logger.ILogger) controller.IController {
|
||||
c.Logger = l
|
||||
c.Db = d
|
||||
c.Session = s
|
||||
|
||||
return nil
|
||||
return c
|
||||
}
|
||||
|
||||
func (h HomePageHandler) Get(w http.ResponseWriter, r *http.Request) error {
|
||||
func (h HomePageController) Get(w http.ResponseWriter, r *http.Request) error {
|
||||
if r.URL.Path != "/" {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
err := layout.NotFound().Render(context.Background(), w)
|
||||
|
@ -3,14 +3,15 @@ package shared
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.markbailey.dev/cerbervs/ptpp/app/controller"
|
||||
"git.markbailey.dev/cerbervs/ptpp/app/session"
|
||||
"git.markbailey.dev/cerbervs/ptpp/lib/database"
|
||||
"git.markbailey.dev/cerbervs/ptpp/lib/database/dto"
|
||||
"git.markbailey.dev/cerbervs/ptpp/lib/logger"
|
||||
"git.markbailey.dev/cerbervs/ptpp/util"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"git.markbailey.dev/cerbervs/ptpp/view/user"
|
||||
)
|
||||
@ -19,48 +20,48 @@ type SignUpHandler struct {
|
||||
controller.Controller
|
||||
}
|
||||
|
||||
func (c SignUpHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) error {
|
||||
func (c SignUpHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) controller.IController {
|
||||
c.Logger = l
|
||||
c.Db = d
|
||||
c.Session = s
|
||||
|
||||
return nil
|
||||
return c
|
||||
}
|
||||
|
||||
type SignInHandler struct {
|
||||
controller.Controller
|
||||
}
|
||||
|
||||
func (c SignInHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) error {
|
||||
func (c SignInHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) controller.IController {
|
||||
c.Logger = l
|
||||
c.Db = d
|
||||
c.Session = s
|
||||
|
||||
return nil
|
||||
return c
|
||||
}
|
||||
|
||||
type PopulateHandler struct {
|
||||
controller.Controller
|
||||
}
|
||||
|
||||
func (c PopulateHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) error {
|
||||
func (c PopulateHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) controller.IController {
|
||||
c.Logger = l
|
||||
c.Db = d
|
||||
c.Session = s
|
||||
|
||||
return nil
|
||||
return c
|
||||
}
|
||||
|
||||
type SignOutHandler struct {
|
||||
controller.Controller
|
||||
}
|
||||
|
||||
func (c SignOutHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) error {
|
||||
func (c SignOutHandler) Init(s session.IManager, d database.IDB, l logger.ILogger) controller.IController {
|
||||
c.Logger = l
|
||||
c.Db = d
|
||||
c.Session = s
|
||||
|
||||
return nil
|
||||
return c
|
||||
}
|
||||
|
||||
func (c PopulateHandler) Get(w http.ResponseWriter, r *http.Request) error {
|
||||
@ -144,7 +145,7 @@ func (c SignInHandler) Post(w http.ResponseWriter, r *http.Request) error {
|
||||
|
||||
foundUser, err := c.Db.Repo().FindUserByUsername(fd.Username)
|
||||
if foundUser == nil || err != nil {
|
||||
return util.Redirect(w, r, "/sign-in", http.StatusSeeOther, false)
|
||||
return util.Redirect(w, r, "/sign-in", http.StatusPermanentRedirect, false)
|
||||
}
|
||||
|
||||
authenticated, err := util.CheckPassword(fd.Password, foundUser.Password)
|
||||
@ -250,6 +251,10 @@ func (c SignUpHandler) Post(w http.ResponseWriter, r *http.Request) error {
|
||||
}
|
||||
|
||||
foundUser, err := c.Db.Repo().FindUserByUsername(fd.Username)
|
||||
if err != nil {
|
||||
c.Db.Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if foundUser != nil {
|
||||
if _, err := w.Write([]byte("Invalid username. Please try another")); err != nil {
|
||||
|
@ -75,15 +75,15 @@ func WithAuth(next http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
if cookie, err = r.Cookie("token"); err != nil {
|
||||
_ = util.Redirect(w, r, "/signin", http.StatusSeeOther, true)
|
||||
_ = util.Redirect(w, r, "/sign-in", http.StatusPermanentRedirect, true)
|
||||
return
|
||||
}
|
||||
if token = cookie.Value; token == "" {
|
||||
_ = util.Redirect(w, r, "/signin", http.StatusSeeOther, true)
|
||||
_ = util.Redirect(w, r, "/sign-in", http.StatusPermanentRedirect, true)
|
||||
return
|
||||
}
|
||||
if claims, err = util.ParseToken(token, os.Getenv("TOKEN_SECRET")); err != nil {
|
||||
_ = util.Redirect(w, r, "/signin", http.StatusSeeOther, true)
|
||||
_ = util.Redirect(w, r, "/sign-in", http.StatusPermanentRedirect, true)
|
||||
return
|
||||
}
|
||||
|
||||
@ -136,5 +136,9 @@ func WithUsername(next http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
func init() {
|
||||
sess, _ = session.NewManager("memory", "ptpp", 3600)
|
||||
var err error
|
||||
sess, err = session.NewManager("memory", "ptpp", 3600)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -15,9 +15,7 @@ templ SignIn(err string) {
|
||||
</h1>
|
||||
<form
|
||||
class="space-y-4 md:space-y-6"
|
||||
action="/sign-in"
|
||||
method="post"
|
||||
hx-post="/signin"
|
||||
hx-post="/sign-in"
|
||||
hx-swap="outerHTML"
|
||||
hx-target="#section"
|
||||
>
|
||||
|
@ -43,7 +43,7 @@ func SignIn(err string) templ.Component {
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<section class=\"bg-gray-50 dark:bg-gray-900\" id=\"section\"><div class=\"flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0\"><div class=\"w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700\"><div class=\"p-6 space-y-4 md:space-y-6 sm:p-8\"><h1 class=\"text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white\">Create an account</h1><form class=\"space-y-4 md:space-y-6\" action=\"/sign-in\" method=\"post\" hx-post=\"/signin\" hx-swap=\"outerHTML\" hx-target=\"#section\"><div><label for=\"username\" class=\"block mb-2 text-sm font-medium text-gray-900 dark:text-white\">Username</label> <input type=\"text\" name=\"username\" id=\"username\" placeholder=\"Username\" class=\"bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500\" required=\"true\"></div><div><label for=\"password\" class=\"block mb-2 text-sm font-medium text-gray-900 dark:text-white\">Password</label> <input type=\"password\" name=\"password\" id=\"password\" placeholder=\"••••••••\" class=\"bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500\" required=\"true\"></div>")
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("<section class=\"bg-gray-50 dark:bg-gray-900\" id=\"section\"><div class=\"flex flex-col items-center justify-center px-6 py-8 mx-auto md:h-screen lg:py-0\"><div class=\"w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700\"><div class=\"p-6 space-y-4 md:space-y-6 sm:p-8\"><h1 class=\"text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white\">Create an account</h1><form class=\"space-y-4 md:space-y-6\" hx-post=\"/sign-in\" hx-swap=\"outerHTML\" hx-target=\"#section\"><div><label for=\"username\" class=\"block mb-2 text-sm font-medium text-gray-900 dark:text-white\">Username</label> <input type=\"text\" name=\"username\" id=\"username\" placeholder=\"Username\" class=\"bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500\" required=\"true\"></div><div><label for=\"password\" class=\"block mb-2 text-sm font-medium text-gray-900 dark:text-white\">Password</label> <input type=\"password\" name=\"password\" id=\"password\" placeholder=\"••••••••\" class=\"bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500\" required=\"true\"></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
@ -55,7 +55,7 @@ func SignIn(err string) templ.Component {
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(err)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/user/signin.templ`, Line: 54, Col: 14}
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/user/signin.templ`, Line: 52, Col: 14}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
|
Loading…
x
Reference in New Issue
Block a user