Skip to content

Commit a6fc945

Browse files
update requireclubmembership middleware
1 parent 346a30f commit a6fc945

File tree

2 files changed

+81
-27
lines changed

2 files changed

+81
-27
lines changed

internal/handlers/server.go

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -179,45 +179,45 @@ func (s *Server) setupRoutes() {
179179
protected.GET("/clubs/:id/poll", postHandler.GetPollPostsByClubID)
180180

181181
protected.POST("/clubs/:id/join", clubHandler.JoinClub)
182-
protected.POST("/clubs/:id/leave", middleware.RequireClubMembership(clubRepo), clubHandler.LeaveClub)
183-
protected.POST("/clubs/:id/ratings", middleware.RequireClubMembership(clubRepo), clubHandler.RateClub)
182+
protected.POST("/clubs/:id/leave", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), clubHandler.LeaveClub)
183+
protected.POST("/clubs/:id/ratings", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), clubHandler.RateClub)
184184
protected.GET("/my-clubs", clubHandler.GetMyClubs)
185185

186186
protected.PUT("/clubs/:id/members/:user_id", middleware.RequireClubMembershipWithRoles(clubRepo, "club_admin", "moderator"), clubHandler.UpdateClubMember)
187187
protected.GET("/clubs/:id/members/:user_id", clubHandler.GetClubMember)
188188

189189
protected.POST("/clubs/:id/events", middleware.RequireClubMembershipWithRoles(clubRepo, "club_admin", "moderator"), eventHandler.CreateEvent)
190-
protected.GET("/clubs/:id/events", middleware.RequireClubMembership(clubRepo), eventHandler.GetClubEvents)
191-
protected.GET("/events/:id", middleware.RequireClubMembership(clubRepo), eventHandler.GetEvent)
190+
protected.GET("/clubs/:id/events", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), eventHandler.GetClubEvents)
191+
protected.GET("/events/:id", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), eventHandler.GetEvent)
192192
protected.PUT("/events/:id", middleware.RequireClubMembershipWithRoles(clubRepo, "club_admin", "moderator"), eventHandler.UpdateEvent)
193193
protected.DELETE("/events/:id", middleware.RequireClubMembershipWithRoles(clubRepo, "club_admin", "moderator"), eventHandler.DeleteEvent)
194194

195-
protected.POST("/events/:id/rsvp", middleware.RequireClubMembership(clubRepo), eventHandler.RSVPToEvent)
196-
protected.GET("/events/:id/attendees", middleware.RequireClubMembership(clubRepo), eventHandler.GetEventAttendees)
195+
protected.POST("/events/:id/rsvp", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), eventHandler.RSVPToEvent)
196+
protected.GET("/events/:id/attendees", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), eventHandler.GetEventAttendees)
197197

198198
protected.POST("/books", middleware.RestrictToRoles("admin", "superuser"), bookHandler.CreateBook)
199199
protected.PUT("/books/:id", middleware.RestrictToRoles("admin", "superuser"), bookHandler.UpdateBook)
200200
protected.DELETE("/books/:id", middleware.RestrictToRoles("admin", "superuser"), bookHandler.DeleteBook)
201201

202-
protected.POST("/posts", middleware.RequireClubMembership(clubRepo), postHandler.CreatePost)
203-
protected.PUT("/posts/:id", middleware.RequireClubMembership(clubRepo), postHandler.UpdatePost)
204-
protected.DELETE("/posts/:id", middleware.RequireClubMembership(clubRepo), postHandler.DeletePost)
205-
protected.GET("/posts/reviews", middleware.RequireClubMembership(clubRepo), postHandler.GetReviewsByBook)
206-
protected.GET("/posts/filter", middleware.RequireClubMembership(clubRepo), postHandler.GetPostsByType)
202+
protected.POST("/posts", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.CreatePost)
203+
protected.PUT("/posts/:id", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.UpdatePost)
204+
protected.DELETE("/posts/:id", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.DeletePost)
205+
protected.GET("/posts/reviews", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.GetReviewsByBook)
206+
protected.GET("/posts/filter", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.GetPostsByType)
207207

208-
protected.POST("/posts/:id/vote", middleware.RequireClubMembership(clubRepo), postHandler.VoteOnPoll)
209-
protected.POST("/posts/:id/unvote", middleware.RequireClubMembership(clubRepo), postHandler.RemoveVoteFromPoll)
210-
protected.GET("/posts/:id/poll/votes", middleware.RequireClubMembership(clubRepo), postHandler.GetUserPollVotes)
208+
protected.POST("/posts/:id/vote", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.VoteOnPoll)
209+
protected.POST("/posts/:id/unvote", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.RemoveVoteFromPoll)
210+
protected.GET("/posts/:id/poll/votes", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.GetUserPollVotes)
211211

212-
protected.POST("/posts/:id/like", middleware.RequireClubMembership(clubRepo), postHandler.LikePost)
213-
protected.POST("/posts/:id/unlike", middleware.RequireClubMembership(clubRepo), postHandler.UnlikePost)
212+
protected.POST("/posts/:id/like", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.LikePost)
213+
protected.POST("/posts/:id/unlike", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), postHandler.UnlikePost)
214214

215-
protected.POST("/posts/:id/comments", middleware.RequireClubMembership(clubRepo), commentHandler.CreateComment)
216-
protected.PUT("/comments/:id", middleware.RequireClubMembership(clubRepo), commentHandler.UpdateComment)
217-
protected.DELETE("/comments/:id", middleware.RequireClubMembership(clubRepo), commentHandler.DeleteComment)
215+
protected.POST("/posts/:id/comments", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), commentHandler.CreateComment)
216+
protected.PUT("/comments/:id", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), commentHandler.UpdateComment)
217+
protected.DELETE("/comments/:id", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), commentHandler.DeleteComment)
218218

219-
protected.POST("/comments/:id/like", middleware.RequireClubMembership(clubRepo), commentHandler.LikeComment)
220-
protected.POST("/comments/:id/unlike", middleware.RequireClubMembership(clubRepo), commentHandler.UnlikeComment)
219+
protected.POST("/comments/:id/like", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), commentHandler.LikeComment)
220+
protected.POST("/comments/:id/unlike", middleware.RequireClubMembership(clubRepo, postRepo, commentRepo), commentHandler.UnlikeComment)
221221

222222
protected.POST("/users/:id/reading/sync", middleware.AuthorizeSelf(), readingHandler.SyncUserStats)
223223
protected.POST("/users/:id/reading/start", middleware.AuthorizeSelf(), readingHandler.StartReading)

internal/middleware/auth.go

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func RestrictToRoles(allowedRoles ...string) gin.HandlerFunc {
124124
}
125125
}
126126

127-
func RequireClubMembership(clubRepo repository.ClubRepository) gin.HandlerFunc {
127+
func RequireClubMembership(clubRepo repository.ClubRepository, postRepo repository.PostRepository, commentRepo repository.CommentRepository) gin.HandlerFunc {
128128
return func(c *gin.Context) {
129129
// allow admin and superuser to bypass club membership check
130130
userRoleRaw, exists := c.Get("user_role")
@@ -147,17 +147,71 @@ func RequireClubMembership(clubRepo repository.ClubRepository) gin.HandlerFunc {
147147
var clubID uint
148148
var err error
149149

150-
clubIDParam := c.Param("id")
150+
path := c.FullPath()
151+
idParam := c.Param("id")
152+
153+
if strings.Contains(path, "/posts/:id") && idParam != "" {
154+
// For post-related routes, get the post and extract club_id
155+
postID, parseErr := strconv.ParseUint(idParam, 10, 32)
156+
if parseErr != nil {
157+
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid post ID"})
158+
c.Abort()
159+
return
160+
}
161+
162+
post, err := postRepo.GetByID(uint(postID))
163+
if err != nil {
164+
if err == gorm.ErrRecordNotFound {
165+
c.JSON(http.StatusNotFound, gin.H{"error": "post not found"})
166+
} else {
167+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to fetch post"})
168+
}
169+
c.Abort()
170+
return
171+
}
172+
clubID = post.ClubID
173+
} else if strings.Contains(path, "/comments/:id") && idParam != "" {
174+
// For comment-related routes, get the comment, then post, then club_id
175+
commentID, parseErr := strconv.ParseUint(idParam, 10, 32)
176+
if parseErr != nil {
177+
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid comment ID"})
178+
c.Abort()
179+
return
180+
}
151181

152-
if clubIDParam != "" {
153-
clubID64, parseErr := strconv.ParseUint(clubIDParam, 10, 32)
182+
comment, err := commentRepo.GetByID(uint(commentID))
183+
if err != nil {
184+
if err == gorm.ErrRecordNotFound {
185+
c.JSON(http.StatusNotFound, gin.H{"error": "comment not found"})
186+
} else {
187+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to fetch comment"})
188+
}
189+
c.Abort()
190+
return
191+
}
192+
193+
post, err := postRepo.GetByID(comment.PostID)
194+
if err != nil {
195+
if err == gorm.ErrRecordNotFound {
196+
c.JSON(http.StatusNotFound, gin.H{"error": "post not found"})
197+
} else {
198+
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to fetch post"})
199+
}
200+
c.Abort()
201+
return
202+
}
203+
clubID = post.ClubID
204+
} else if strings.Contains(path, "/clubs/:id") && idParam != "" {
205+
// For direct club routes (e.g., /clubs/:id/posts)
206+
clubID64, parseErr := strconv.ParseUint(idParam, 10, 32)
154207
if parseErr != nil {
155208
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid club ID"})
156209
c.Abort()
157210
return
158211
}
159212
clubID = uint(clubID64)
160213
} else {
214+
// Try to get club_id from request body
161215
bodyBytes, readErr := c.GetRawData()
162216
if readErr != nil {
163217
c.JSON(http.StatusBadRequest, gin.H{"error": "unable to read request body"})
@@ -174,7 +228,7 @@ func RequireClubMembership(clubRepo repository.ClubRepository) gin.HandlerFunc {
174228
if json.Unmarshal(bodyBytes, &reqBody) == nil && reqBody.ClubID > 0 {
175229
clubID = reqBody.ClubID
176230
} else {
177-
c.JSON(http.StatusBadRequest, gin.H{"error": "club_id is required in body"})
231+
c.JSON(http.StatusBadRequest, gin.H{"error": "club_id is required"})
178232
c.Abort()
179233
return
180234
}
@@ -284,4 +338,4 @@ func OptionalAuthMiddleware(cfg *config.Config) gin.HandlerFunc {
284338
c.Set("user_role", claims.Role)
285339
c.Next()
286340
}
287-
}
341+
}

0 commit comments

Comments
 (0)