package main import ( "fmt" "log" "github.com/gin-contrib/sessions" "github.com/gin-contrib/sessions/cookie" "github.com/gin-gonic/gin" "go_blog/config" "go_blog/handlers" "go_blog/middleware" "go_blog/models" ) func main() { // 1. Load configuration (auto-creates if missing). cfg := config.LoadConfig() // 2. Initialize the database (auto-migrates, seeds admin). db := models.InitDB(cfg) // 2b. Warm the platform configuration cache from the database. models.LoadConfigCache(db) // 3. Create session store (cookie-based). store := cookie.NewStore([]byte(cfg.Secret)) store.Options(sessions.Options{ Path: "/", MaxAge: 86400, // 24 hours HttpOnly: true, // prevent XSS access Secure: false, // set true in production with HTTPS }) // 4. Create Gin router. router := gin.Default() // 5. Load HTML templates. router.LoadHTMLGlob("templates/**/*.html") // 6. Serve uploaded files (avatars etc.) from the storage path. router.Static("/uploads", cfg.Path) // 6. Global session middleware. router.Use(sessions.Sessions("blog_session", store)) // 7. Global context middleware (sets IsLoggedIn, Username for templates). router.Use(middleware.SetUserContext(db)) // 8. Register routes. router.GET("/", handlers.HomePage(db)) router.GET("/login", handlers.LoginPage()) router.POST("/login", handlers.Login(db)) router.POST("/logout", handlers.Logout()) router.GET("/article/:slug", handlers.ArticleDetail(db)) router.POST("/article/:slug/comments", handlers.PostComment(db)) // Protected admin routes. admin := router.Group("/admin") admin.Use(middleware.AuthRequired()) { admin.GET("", handlers.AdminDashboard(db)) admin.GET("/articles", handlers.ArticleListPage(db)) admin.GET("/articles/new", handlers.ArticleCreatePage(db)) admin.POST("/articles/new", handlers.ArticleCreate(db)) admin.GET("/articles/:id/edit", handlers.ArticleEditPage(db)) admin.POST("/articles/:id/edit", handlers.ArticleUpdate(db)) admin.POST("/articles/:id/delete", handlers.ArticleDelete(db)) admin.GET("/comments", handlers.CommentListPage(db)) admin.POST("/comments/:id/approve", handlers.CommentApprove(db)) admin.POST("/comments/:id/reject", handlers.CommentReject(db)) admin.POST("/comments/:id/delete", handlers.CommentDelete(db)) } // Protected article attachment routes (AJAX uploads / management). attachments := router.Group("/admin/articles") attachments.Use(middleware.AuthRequired()) { attachments.POST("/attachments", handlers.UploadAttachment(db, cfg.Path)) attachments.POST("/attachments/:id/delete", handlers.DeleteAttachment(db, cfg.Path)) attachments.GET("/:id/attachments", handlers.ListAttachments(db)) } // Protected admin settings routes (platform configuration). settings := router.Group("/admin/settings") settings.Use(middleware.AuthRequired()) { settings.GET("/site", handlers.SiteSettingsPage(db)) settings.POST("/site", handlers.SiteSettingsSave(db, cfg.Path)) settings.GET("/upload", handlers.UploadSettingsPage(db)) settings.POST("/upload", handlers.UploadSettingsSave(db)) settings.GET("/download", handlers.DownloadSettingsPage(db)) settings.POST("/download", handlers.DownloadSettingsSave(db)) settings.GET("/comments", handlers.CommentSettingsPage(db)) settings.POST("/comments", handlers.CommentSettingsSave(db)) } // Protected profile routes. profile := router.Group("/profile") profile.Use(middleware.AuthRequired()) { profile.GET("", handlers.ProfilePage(db)) profile.POST("", handlers.UpdateProfile(db, cfg.Path)) profile.POST("/avatar", handlers.UploadAvatar(db, cfg.Path)) } // 9. Start the server. addr := fmt.Sprintf(":%s", cfg.Port) log.Printf("Go Blog starting on http://localhost%s", addr) if err := router.Run(addr); err != nil { log.Fatalf("Failed to start server: %v", err) } }