diff --git a/cmd/wg-portal/assets/tpl/error.gohtml b/cmd/wg-portal/assets/tpl/error.gohtml index 1a12e1c..4d6cdd0 100644 --- a/cmd/wg-portal/assets/tpl/error.gohtml +++ b/cmd/wg-portal/assets/tpl/error.gohtml @@ -1,33 +1,44 @@ + - - {{ .Static.WebsiteTitle }} - Error + + {{ .Static.WebsiteTitle }} - + {{template "prt_nav.gohtml" .}} -
+
+ {{with $.Error}}
-
-

{{.Data.Code}}

+
+

{{$.ErrorCode}}

-

{{.Data.Message}}

-

{{.Data.Details}}

← Back to Dashboard +

{{$.Error}}

+

{{$.ErrorDetails}}

+
+ {{end}} + {{with not $.Error}} +
+
+

{{$.ErrorCode}}

+
+

Oops... something unexpected happened...

+
+ {{end}} + +
{{template "prt_footer.gohtml" .}} - - - - \ No newline at end of file diff --git a/cmd/wg-portal/assets/tpl/prt_nav.gohtml b/cmd/wg-portal/assets/tpl/prt_nav.gohtml index 2b10eec..3f68770 100644 --- a/cmd/wg-portal/assets/tpl/prt_nav.gohtml +++ b/cmd/wg-portal/assets/tpl/prt_nav.gohtml @@ -29,8 +29,8 @@ {{with startsWith $.Route "/admin/"}}
diff --git a/cmd/wg-portal/ui/handler.go b/cmd/wg-portal/ui/handler.go index 1c45358..1f4206d 100644 --- a/cmd/wg-portal/ui/handler.go +++ b/cmd/wg-portal/ui/handler.go @@ -2,6 +2,7 @@ import ( "context" + "fmt" "net/http" "net/url" "path" @@ -163,8 +164,15 @@ }, }) + g.NoRoute(func(c *gin.Context) { + h.HandleError(c, http.StatusNotFound, + errors.New("Oops... you have reached the end of the internet"), + fmt.Sprintf("Requested page %s not found", c.Request.URL.Path)) + }) + // Entrypoint g.GET("/", h.handleIndexGet()) + g.GET("/oops", h.handleErrorGet()) // Auth routes auth := g.Group("/auth") @@ -185,6 +193,26 @@ // User routes } +func (h *handler) HandleError(c *gin.Context, code int, err error, details string) { + currentSession := h.session.GetData(c) + + currentSession.Error = &ErrorData{ + Message: err.Error(), + Details: details, + Code: code, + Path: c.Request.URL.Path, + } + + // If page was not found, redirect to / + if code == http.StatusNotFound { + currentSession.Error.Path = "/" + } + + h.session.SetData(c, currentSession) + + c.Redirect(http.StatusSeeOther, "/oops") +} + // // -- // diff --git a/cmd/wg-portal/ui/pages_admin.go b/cmd/wg-portal/ui/pages_admin.go index b8e4182..ae0c238 100644 --- a/cmd/wg-portal/ui/pages_admin.go +++ b/cmd/wg-portal/ui/pages_admin.go @@ -1,6 +1,7 @@ package ui import ( + "fmt" "net/http" "github.com/h44z/wg-portal/internal/persistence" @@ -12,6 +13,19 @@ return func(c *gin.Context) { currentSession := h.session.GetData(c) + interfaces, err := h.backend.GetInterfaces() + if err != nil { + h.HandleError(c, http.StatusInternalServerError, err, "failed to load available interfaces") + return + } + + _, err = h.backend.GetInterface(currentSession.InterfaceIdentifier) + if err != nil { + h.HandleError(c, http.StatusInternalServerError, err, + fmt.Sprintf("failed to load selected interface %s", currentSession.InterfaceIdentifier)) + return + } + c.HTML(http.StatusOK, "admin_index.gohtml", gin.H{ "Route": c.Request.URL.Path, "Alerts": h.session.GetFlashes(c), @@ -93,8 +107,8 @@ }, }, }, - "InterfaceNames": map[string]string{"wgX": "wgX descr"}, - "TotalPeers": 12, + "Interfaces": interfaces, + "TotalPeers": 12, }) } } diff --git a/cmd/wg-portal/ui/pages_core.go b/cmd/wg-portal/ui/pages_core.go index 44b2789..52ca9ae 100644 --- a/cmd/wg-portal/ui/pages_core.go +++ b/cmd/wg-portal/ui/pages_core.go @@ -34,13 +34,49 @@ return func(c *gin.Context) { currentSession := h.session.GetData(c) + interfaces, err := h.backend.GetInterfaces() + if err != nil { + h.HandleError(c, http.StatusInternalServerError, err, "failed to load available interfaces") + return + } + c.HTML(http.StatusOK, "index.gohtml", gin.H{ - "Route": c.Request.URL.Path, - "Alerts": h.session.GetFlashes(c), - "Session": currentSession, - "Static": h.getStaticData(), - "Interface": nil, // TODO: load interface specified in the session - "InterfaceNames": map[string]string{"wgX": "wgX descr"}, + "Route": c.Request.URL.Path, + "Alerts": h.session.GetFlashes(c), + "Session": currentSession, + "Static": h.getStaticData(), + "Interface": nil, // TODO: load interface specified in the session + "Interfaces": interfaces, + }) + } +} + +func (h *handler) handleErrorGet() gin.HandlerFunc { + return func(c *gin.Context) { + currentSession := h.session.GetData(c) + + var ( + err = "" + errorCode = http.StatusNotFound + details = "" + path = "/" + ) + if currentSession.Error != nil { + err = currentSession.Error.Message + details = currentSession.Error.Details + errorCode = currentSession.Error.Code + path = currentSession.Error.Path + } + + c.HTML(errorCode, "error.gohtml", gin.H{ + "Route": c.Request.URL.Path, + "Alerts": h.session.GetFlashes(c), + "Session": currentSession, + "Static": h.getStaticData(), + "ErrorCode": errorCode, + "Error": err, + "ErrorDetails": details, + "PreviousRoute": path, }) } } diff --git a/cmd/wg-portal/ui/session.go b/cmd/wg-portal/ui/session.go index a2be92c..0198dc1 100644 --- a/cmd/wg-portal/ui/session.go +++ b/cmd/wg-portal/ui/session.go @@ -12,6 +12,7 @@ func init() { gob.Register(SessionData{}) gob.Register(FlashData{}) + gob.Register(ErrorData{}) } type SessionData struct { @@ -42,6 +43,16 @@ // currently filled form data FormData interface{} + + // Session error + Error *ErrorData +} + +type ErrorData struct { + Message string + Details string + Code int + Path string } type FlashData struct {