1package httpserve
2
3import (
4 "github.com/bnema/gordon/internal/httpserve/handler"
5 "github.com/bnema/gordon/internal/httpserve/middleware"
6 "github.com/bnema/gordon/internal/server"
7 _ "github.com/joho/godotenv/autoload"
8 "github.com/labstack/echo/v4"
9)
10
11// RegisterRoutes registers all routes for the application
12func RegisterRoutes(e *echo.Echo, a *server.App) *echo.Echo {
13 // --- Register API endpoints --- //
14 bindAPIEndpoints(e, a)
15 AdminPath := a.Config.Admin.Path
16 // SetCommonDataMiddleware will pass data to the renderer
17 e.Use(middleware.SetCommonDataMiddleware(a))
18 // Error handler middleware
19 e.Use(middleware.ErrorHandler)
20
21 // Initiate the session middleware
22 e.Use(middleware.InitSessionMiddleware(a))
23 // Use middlewares
24 e.Use(middleware.SecureRoutes())
25
26 // Color scheme detection for dark/light mode
27 e.Use(middleware.ColorSchemeDetection)
28 // Language detection
29 e.Use(middleware.LanguageDetection)
30
31 // --- Register routes --- //
32 bindAdminRoute(e, a, AdminPath)
33 bindStaticRoute(e, a, "/*")
34 bindLoginRoute(e, a, AdminPath)
35 bindHTMXEndpoints(e, a)
36 // Protect the root path with a 403
37 e.GET("/", func(c echo.Context) error {
38 return c.String(403, "403 Forbidden")
39 })
40
41 return e
42}
43
44// bindAPIEndpoints expose /api endpoints and speaks only JSON
45func bindAPIEndpoints(e *echo.Echo, a *server.App) {
46 apiGroup := e.Group("/api")
47 apiGroup.Use(middleware.RequireToken(a))
48 apiGroup.GET("/hello", func(c echo.Context) error {
49 return handler.GetHello(c, a)
50 })
51 apiGroup.GET("/ping", func(c echo.Context) error {
52 return handler.GetInfos(c, a)
53 })
54 apiGroup.POST("/push", func(c echo.Context) error {
55 return handler.PostPush(c, a)
56 })
57}
58
59// bindStaticRoute bind static path
60func bindStaticRoute(e *echo.Echo, a *server.App, path string) {
61 e.GET(path, func(c echo.Context) error {
62 return handler.StaticRoute(c, a)
63 })
64}
65
66// bindLoginRoute binds all login routes
67func bindLoginRoute(e *echo.Echo, a *server.App, adminPath string) {
68 e.GET(adminPath+"/login", func(c echo.Context) error {
69 return handler.RenderLoginPage(c, a)
70 })
71 e.GET(adminPath+"/login/oauth/github", func(c echo.Context) error {
72 return handler.StartOAuthGithub(c, a)
73 })
74 e.GET(adminPath+"/login/oauth/callback", func(c echo.Context) error {
75 return handler.OAuthCallback(c, a)
76 })
77 e.GET(adminPath+"/logout", func(c echo.Context) error {
78 return c.HTML(200, "<h1>Logout</h1>")
79 })
80}
81
82// bindAdminRoute binds all admin routes
83func bindAdminRoute(e *echo.Echo, a *server.App, adminPath string) {
84 adminGroup := e.Group(adminPath)
85 // Since login is behind the admin path, we cannot use group middleware
86 adminGroup.GET("", func(c echo.Context) error {
87 return c.Redirect(302, adminPath+"/manager")
88 }, middleware.RequireLogin(a))
89
90 adminGroup.GET("/manager", func(c echo.Context) error {
91 return handler.AdminManagerRoute(c, a)
92 }, middleware.RequireLogin(a))
93}
94
95// bindHTMXEndpoints binds all HTMX endpoints
96func bindHTMXEndpoints(e *echo.Echo, a *server.App) {
97 // Create a group for /htmx endpoints
98 htmxGroup := e.Group("/htmx")
99
100 // Apply middleware to the group, so all endpoints are protected
101 htmxGroup.Use(middleware.RequireLogin(a))
102
103 // List all images component
104 htmxGroup.GET("/image-manager", func(c echo.Context) error {
105 return handler.ImageManagerComponent(c, a)
106 })
107 // Delete an image
108 htmxGroup.DELETE("/image-manager/delete/:ID", func(c echo.Context) error {
109 return handler.ImageManagerDelete(c, a)
110 })
111
112 // List all containers
113 htmxGroup.GET("/container-manager", func(c echo.Context) error {
114 return handler.ContainerManagerComponent(c, a)
115 })
116 // Stop a container
117 htmxGroup.POST("/container-manager/stop/:ID", func(c echo.Context) error {
118 return handler.ContainerManagerStop(c, a)
119 })
120 // Delete a container
121 htmxGroup.DELETE("/container-manager/delete/:ID", func(c echo.Context) error {
122 return handler.ContainerManagerDelete(c, a)
123 })
124 // Start a container
125 htmxGroup.POST("/container-manager/start/:ID", func(c echo.Context) error {
126 return handler.ContainerManagerStart(c, a)
127 })
128 // Edit a container view
129 htmxGroup.GET("/container-manager/edit/:ID", func(c echo.Context) error {
130 return handler.ContainerManagerEditGET(c, a)
131 })
132 // Edit a container action
133 htmxGroup.POST("/container-manager/edit/:ID", func(c echo.Context) error {
134 return handler.ContainerManagerEditPOST(c, a)
135 })
136
137 // Display upload-image component
138 htmxGroup.GET("/upload-image", func(c echo.Context) error {
139 return handler.UploadImageGETHandler(c, a)
140 })
141 // Upload image
142 htmxGroup.POST("/upload-image", func(c echo.Context) error {
143 return handler.UploadImagePOSTHandler(c, a)
144 })
145 // Display create-container component
146 htmxGroup.GET("/create-container/:ID", func(c echo.Context) error {
147 return handler.CreateContainerGET(c, a)
148 })
149 // Create container
150 htmxGroup.POST("/create-container/:ID", func(c echo.Context) error {
151 return handler.CreateContainerPOST(c, a)
152 })
153}