feat: add role-based access control and user article management
- Add AdminRequired middleware to all /admin routes for proper authorization - Restrict admin panel, comments, users, settings to admin role only - Create separate /my/articles routes for regular users to manage their own articles - Add MyArticlesPage handler for users to view/edit/delete their own content - Update navigation menus with role-based visibility - Admin dropdown shows only 'Admin Panel' link, other features in dashboard - Regular users see 'My Articles' link in profile dropdown - Add i18n translations for 'my_articles' and 'comment_manage' keys - Fix permission boundary issues where author role could access admin settings Security improvements: - Platform settings now require admin role - Comment moderation requires admin role - User management requires admin role - Regular users can only manage their own articles Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,9 +56,9 @@ func main() {
|
||||
router.GET("/article/:slug", handlers.ArticleDetail(db))
|
||||
router.POST("/article/:slug/comments", handlers.PostComment(db))
|
||||
|
||||
// Protected admin routes.
|
||||
// Protected admin routes (admin role only).
|
||||
admin := router.Group("/admin")
|
||||
admin.Use(middleware.AuthRequired())
|
||||
admin.Use(middleware.AuthRequired(), middleware.AdminRequired(db))
|
||||
{
|
||||
admin.GET("", handlers.AdminDashboard(db))
|
||||
admin.GET("/articles", handlers.ArticleListPage(db))
|
||||
@@ -68,10 +68,16 @@ func main() {
|
||||
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 admin comment management routes (admin role only).
|
||||
comments := router.Group("/admin/comments")
|
||||
comments.Use(middleware.AuthRequired(), middleware.AdminRequired(db))
|
||||
{
|
||||
comments.GET("", handlers.CommentListPage(db))
|
||||
comments.POST("/:id/approve", handlers.CommentApprove(db))
|
||||
comments.POST("/:id/reject", handlers.CommentReject(db))
|
||||
comments.POST("/:id/delete", handlers.CommentDelete(db))
|
||||
}
|
||||
|
||||
// Protected admin user-management routes (admin role only).
|
||||
@@ -86,9 +92,9 @@ func main() {
|
||||
users.POST("/:id/delete", handlers.UserDelete(db))
|
||||
}
|
||||
|
||||
// Protected article attachment routes (AJAX uploads / management).
|
||||
// Protected article attachment routes (admin role only).
|
||||
attachments := router.Group("/admin/articles")
|
||||
attachments.Use(middleware.AuthRequired())
|
||||
attachments.Use(middleware.AuthRequired(), middleware.AdminRequired(db))
|
||||
{
|
||||
attachments.POST("/attachments", handlers.UploadAttachment(db, cfg.Path))
|
||||
attachments.POST("/attachments/:id/delete", handlers.DeleteAttachment(db, cfg.Path))
|
||||
@@ -97,7 +103,7 @@ func main() {
|
||||
|
||||
// Protected admin settings routes (platform configuration).
|
||||
settings := router.Group("/admin/settings")
|
||||
settings.Use(middleware.AuthRequired())
|
||||
settings.Use(middleware.AuthRequired(), middleware.AdminRequired(db))
|
||||
{
|
||||
settings.GET("/site", handlers.SiteSettingsPage(db))
|
||||
settings.POST("/site", handlers.SiteSettingsSave(db, cfg.Path))
|
||||
@@ -118,6 +124,27 @@ func main() {
|
||||
profile.POST("/avatar", handlers.UploadAvatar(db, cfg.Path))
|
||||
}
|
||||
|
||||
// Protected user article management routes (for non-admin users).
|
||||
myArticles := router.Group("/my")
|
||||
myArticles.Use(middleware.AuthRequired())
|
||||
{
|
||||
myArticles.GET("/articles", handlers.MyArticlesPage(db))
|
||||
myArticles.GET("/articles/new", handlers.MyArticleCreatePage(db))
|
||||
myArticles.POST("/articles/new", handlers.MyArticleCreate(db))
|
||||
myArticles.GET("/articles/:id/edit", handlers.MyArticleEditPage(db))
|
||||
myArticles.POST("/articles/:id/edit", handlers.MyArticleUpdate(db))
|
||||
myArticles.POST("/articles/:id/delete", handlers.MyArticleDelete(db))
|
||||
}
|
||||
|
||||
// Protected article attachment routes for user articles.
|
||||
myAttachments := router.Group("/my/articles")
|
||||
myAttachments.Use(middleware.AuthRequired())
|
||||
{
|
||||
myAttachments.POST("/attachments", handlers.UploadAttachment(db, cfg.Path))
|
||||
myAttachments.POST("/attachments/:id/delete", handlers.DeleteAttachment(db, cfg.Path))
|
||||
myAttachments.GET("/:id/attachments", handlers.ListAttachments(db))
|
||||
}
|
||||
|
||||
// 9. Start the server.
|
||||
addr := fmt.Sprintf(":%s", cfg.Port)
|
||||
log.Printf("Go Blog starting on http://localhost%s", addr)
|
||||
|
||||
Reference in New Issue
Block a user