package middleware import ( "net/http" "github.com/gin-gonic/gin" "git.gobha.me/xcaliber/chat-switchboard/database" ) // RequireTeamAdmin returns middleware that restricts access to users who are // admins of the team identified by :teamId in the URL path. // System admins (role=admin) are always allowed through. // Must be used after Auth() middleware. func RequireTeamAdmin() gin.HandlerFunc { return func(c *gin.Context) { // System admins bypass team check role, _ := c.Get("role") if role == "admin" { c.Next() return } userID, _ := c.Get("user_id") teamID := c.Param("teamId") if teamID == "" { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ "error": "team ID required", }) return } var teamRole string err := database.DB.QueryRow(` SELECT role FROM team_members WHERE team_id = $1 AND user_id = $2 `, teamID, userID).Scan(&teamRole) if err != nil || teamRole != "admin" { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{ "error": "team admin access required", }) return } c.Next() } } // RequireTeamMember returns middleware that restricts access to users who // belong to the team identified by :teamId (any role). // System admins are always allowed through. func RequireTeamMember() gin.HandlerFunc { return func(c *gin.Context) { role, _ := c.Get("role") if role == "admin" { c.Next() return } userID, _ := c.Get("user_id") teamID := c.Param("teamId") if teamID == "" { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{ "error": "team ID required", }) return } var exists bool database.DB.QueryRow(` SELECT EXISTS(SELECT 1 FROM team_members WHERE team_id = $1 AND user_id = $2) `, teamID, userID).Scan(&exists) if !exists { c.AbortWithStatusJSON(http.StatusForbidden, gin.H{ "error": "team membership required", }) return } c.Next() } }